标签:
标签:快学scala
val ‘val‘ = 42
所有的操作符都是左结合的,除了以冒号(:)结尾的操作符,和赋值操作符。用于构造列表的::操作符是又结合的。1::2::Ni1的意思是1::(2::Ni1),先创建出包含2的列表,这个列表又被作为尾巴拼接到以1作为头部的列表中。
2. 函数调用语法:f(arg1, arg2,...)扩展到可以应用于函数之外的值,如果f不是函数或方法,那么这个表达式等于f.apply(arg1,arg2,....)。除非它出现在赋值语句的等号左侧。
f(arg1,arg2,...) = value 等同于如下调用f.update(arg1,arg2,....,value)
object Fraction{def unapply(input: Fraction)=if(input.den == 0) None else Some((input.num, input.den))} //方法在分母为0时返回None,表示无匹配。
object Name{def unapplySeq(input: String): Option[Seq[A]] =if(input.trim == "") None else Some(input.trim.split("\\s+"))}//匹配任意数量的变量author match{case Name(first, last) =>..case Name(first, middle,last)=>.....}
11.1 根据优先级规则,3 + 4 -> 5和3 -> 4 + 5是如何被求值的?
都是从左至右执行,所以 3 -> 4 + 5表达式是不合法的。
11.2 BigInt类有一个pow方法,但没有用操作符字符。Scala类库的设计者为什么没有选用**(像Fortran那样)或者^(像Pascal那样)作为乘方操作符呢?
scala中操作符就是方法,优先级是根据首字母来判断的。
最高优先级:除以下字符外的操作符字符* / %+ -:= !< >&?|非操作符最低优先级:赋值操作符
一般乘方操作符优先于乘法操作,如果使用**作为乘方的话,那么其优先级则与*相同,而如果使用^的话,则优先级低于*操作。优先级都是有问题的。故没有使用这两种操作符。
11.3 实现Fraction类,支持+*/操作。支持约分,例如将15/-6变为-5/2。除以最大公约数,像这样:
class Fraction(n:Int,d:Int){private val num:Int = if(d==0) 1 else n * sign(d)/gcd(n,d);private val den:Int = if(d==0) 0 else d * sign(d)/gcd(n,d);override def toString = num + "/" + dendef sign(a:Int) = if(a > 0) 1 else if (a < 0) -1 else 0def gcd(a:Int,b:Int):Int = if(b==0) abs(a) else gcd(b,a%b)...}
import scala.math.absclass Fraction(n: Int, d: Int){private val num: Int = if(d == 0)1 else n *sign(d)/gcd(n,d)private val den: Int = if(d == 0)0 else d * sign(d)/gcd(n,d)override def toString = num + "/" +dendef sign(a: Int) = if(a >0)1 else if(a <0) -1 else 0def gcd(a: Int, b: Int): Int = if(b == 0) abs(a) else gcd(b, a%b)def +(other: Fraction): Fraction= {new Fraction((this.num * other.den) + (other.num *this.den), this.den * other.den)}def -(other: Fraction): Fraction={new Fraction((this.num * other.den) - (other.num *this.den), this.den * other.den)}def *(other: Fraction): Fraction={new Fraction(this.num * other.num, this.den * other.den)}def / (other: Fraction): Fraction={new Fraction(this.num * other.den, this.den * other.num)}}object Fraction{def apply(n: Int, d: Int) = new Fraction(n, d)}val x = Fraction(15, -6)val y = Fraction(20,60)println(x)println( x + y)println( x * y)
11.4 实现一个Money类,加入美元和美分字段。提供+,-操作符以及比较操作符==和<。举例来说,Money(1,75)+Money(0,50)==Money(2,25)应为true。你应该同时提供*和/操作符吗?为什么?
class Money(d: BigInt, c: BigInt) extends Ordered[Money]{val dollars: BigInt = d + c /100val cents: BigInt = c % 100override def toString() = "%d.%d".format(dollars, cents)def toCents(): BigInt = dollars * 100 + centsdef fromCents(cents: BigInt) = new Money(cents / 100, cents % 100)override def compare(that: Money): Int = toCents.compare(that.toCents)def + (that: Money) = fromCents(this.toCents + that.toCents)def - (that: Money) = fromCents(this.toCents - that.toCents)}object Money{def apply(d: Int, c: Int) = new Money(d, c)}val x = Money(1, 75)val y = Money(0, 50)println(x + y)println(x - y)println(x > y) //true
11.5 提供操作符用于构造HTML表格。例如:Table() | "Java" | "Scala" || "Gosling" | "Odersky" || "JVM" | "JVM,.NET"应产出
:<table><tr><td>Java</td></tr><td>Scala</td></tr><tr><td>Gosling…
import collection.mutable.ArrayBufferclass Table{private val chunks = new ArrayBuffer[String]def | (chunk: String)= {chunks += "<td>%s</td>\n".format(chunk)this}def ||(chunk: String) = {chunks += "</tr><tr>\n<td>%s</td>".format(chunk)this}override def toString = "<table><tr>\n%s</tr><table".format(chunks.mkString)}object Table{def apply() = new Table()}val t = Table() | "Java" | "Scala" || "Gosling" | "Odersky" || "JVM" | "JVM,.NET"println(t)
11.6 提供一个ASCIIArt类,其对象包含类似这样的图形:
/\_/\( ‘ ‘ )( - )| | |(__|__)提供将两个ASCIIArt图形横向或纵向结合的操作符。选用适当优先级的操作符命名。纵向结合的实例/\_/\ -----( ‘ ‘ ) / Hello \( - ) < Scala || | | \ Coder /(__|__) -----
class ASCIIArt(val art: String){def +(other: ASCIIArt) = new ASCIIArt(art.split("\n").zip(other.art.split("\n")).map(x => x._1 + x._2).mkString("\n"))def ^(other: ASCIIArt) = new ASCIIArt( art + "\n" + other.art)override def toString = art}val x = new ASCIIArt(""" /\_/\( ‘ ‘ )( - )| | |(__|__)""")val y = new ASCIIArt(""" -----/ Hello \< Scala |\ Coder /-----""")println(x + y)println(x ^ y)
11.7 实现一个BigSequence类,将64个bit的序列打包在一个Long值中。提供apply和update操作来获取和设置某个具体的bit
class BitSequence(private var value: Long = 0){implicit def bool2int(b: Boolean) = if(b) 1 else 0def update(bit: Int, state: Int) = value |= (state & 1L)<< bit % 64def apply(bit: Int): Int = if((value & 1L << bit % 64) > 0) 1 else 0override def toString = "%64s".format(value.toBinaryString).replace(" ", "0")}val x = new BitSequence()x(5) = 1x(63) = 1x(64) = 1println(x(5))println(x)
11.8 提供一个Matrix类—你可以选择需要的是一个2*2的矩阵,任意大小的正方形矩阵,或m*n的矩阵。支持+和操作。操作应同样适用于单值,例如mat*2。单个元素可以通过mat(row,col)得到
class Matrix(val m: Int, val n: Int){private val value = Array.ofDim[Double](m, n)def update(x: Int, y: Int, v: Double) = value(x)(y) = vdef apply(x: Int, y: Int) = value(x)(y)def +(other: Matrix) = {require (n == other.n)require (m == other.m)var res = new Matrix(m,n)for(i <- 0 until m; j <- 0 until n){res(i, j) = this.value(i)(j) + other.value(i)(j)}res}def *(factor: Double) = {var res = new Matrix(m, n)for(i <- 0 until m; j <- 0 until n) {res(i, j) = this.value(i)(j) * factor}res}private def prod(other: Matrix, i: Int, j: Int) = {(for (k <- 0 until n) yield value(i)(k) * other.value(j)(k)).sum}def *(other: Matrix) = {require(n == other.m)var res = new Matrix(m, n)for(i <- 0 until m; j <- 0 until n) {res(i, j) = prod(other, i, j)}res}override def toString = value.map(_.mkString(" ")).mkString("\n")}val x = new Matrix(2,3)x(0, 0) = 1x(0, 0) = 1x(1, 0) = 3x(1, 1) = 4println(x)println()println(x * 2)println()
11.9 为RichFile类定义unapply操作,提取文件路径,名称和扩展名。举例来说,文件/home/cay/readme.txt的路径为/home/cay,名称为readme,扩展名为txt
object RichFile{def unapply(s: String) = {val pos = s.lastIndexOf("/")if(pos == -1) None else Some((s.substring(0, pos), s.substring(pos+1)))}}val RichFile(path, name) = "/home/user/scala/test.txt"println("Path: %s, File: %s".format(path, name))
11.10 为RichFile类定义一个unapplySeq,提取所有路径段。举例来说,对于/home/cay/readme.txt,你应该产出三个路径段的序列:home,cay和readme.txt
object RichFile {def unapplySeq(s: String): Option[Seq[String]] = {if (s.trim == "") None else Some(s.trim.split("/"))}}val RichFile(first, middle, last) = "home/user/text.txt"println("First: %s, Middle: %s, Last: %s".format(first, middle, last))
标签:
原文地址:http://blog.csdn.net/refuil/article/details/51991601