第十一章:操作符
标签(空格分隔): scala课后习题
1.根据优先级规则,3 + 4 -> 5和3 -> 4 + 5是如何被求值的?
都是从左到右,貌似 3->4+5 会编译不过去。
2. BigInt类有一个pow方法,但没有用操作符字符。Scala类库的设计者为什么没有选用**
(像Fortran那样)或者^(像Pascal那样)作为乘方操作符呢?
Scala中的操作符就是方法,其优先级是根据首字母来判断的,一般乘方的操作符是优于乘法操作的,如果使用*作为乘方的话,那么其优先级则与相同,而如果使用^的话,则优先级低于*操作。
3 实现Fraction类,支持+*/操作。支持约分,例如将15/-6变为-5/2。
import scala.math.abs
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 + "/" + den
def sign(a: Int) = if (a > 0) 1 else if (a < 0) -1 else 0
def gcd(a: Int, b: Int): Int = if (b == 0) abs(a) else gcd(b, a % b)
def +(other:Fraction):Fraction={
newFrac((this.num * other.den) + (other.num * this.den),this.den * other.den)
}
def -(other:Fraction):Fraction={
newFrac((this.num * other.den) - (other.num * this.den),this.den * other.den)
}
def *(other:Fraction):Fraction={
newFrac(this.num * other.num,this.den * other.den)
}
def /(other:Fraction):Fraction={
newFrac(this.num * other.den,this.den * other.num)
}
private def newFrac(a:Int,b:Int):Fraction={
val x:Int = if (b == 0) 1 else a * sign(b) / gcd(a, b);
val y:Int = if (b == 0) 0 else b * sign(b) / gcd(a, b);
new Fraction(x,y)
}
}
object Test extends App{
val f = new Fraction(15,-6)
val p = new Fraction(20,60)
println(f)
println(p)
println(f + p)
println(f - p)
println(f * p)
println(f / p)
}
5. 提供操作符用于构造HTML表格。例如:Table() | “Java” | “Scala” || “Gosling” | “Odersky” || “JVM” | “JVM,.NET”应产出:<table><tr><td>Java</td></tr><td>Scala</td></tr><tr><td>Goling...
class Table{
private var s:String = ""
def |(str:String):Table={
s +="<td>" + str + "</td>"
this
}
def ||(str:String):Table={
s += "</tr><tr><td>" + str + "</td>"
this
}
override def toString():String={
"<table><tr>" + this.s + "</tr></table>"
}
}
object Table{
def apply():Table={
new Table()
}
def main(args: Array[String]) {
println(Table() | "Java" | "Scala" || "Gosling" | "Odersky" || "JVM" | "JVM,.NET")
}
}
9.为RichFile类定义unapply操作,提取文件路径,名称和扩展名。举例来说,文件/home/cay/readme.txt的路径为/home/cay,名称为readme,扩展名为txt
class RichFile(val path:String){}
object RichFile{
def apply(path:String):RichFile={
new RichFile(path)
}
def unapply(richFile:RichFile) = {
if(richFile.path == null){
None
} else {
val reg = "([/\\w+]+)/(\\w+)\\.(\\w+)".r
val reg(r1,r2,r3) = richFile.path
Some((r1,r2,r3))
}
}
def main(args: Array[String]) {
val richFile = RichFile("/home/cay/readme.txt")
val RichFile(r1,r2,r3) = richFile
println(r1)
println(r2)
println(r3)
}
}
10.为RichFile类定义一个unapplySeq,提取所有路径段。举例来说,对于/home/cay/readme.txt,你应该产出三个路径段的序列:home,cay和readme.txt
class RichFile(val path:String){}
object RichFile{
def apply(path:String):RichFile={
new RichFile(path)
}
def unapplySeq(richFile:RichFile):Option[Seq[String]]={
if(richFile.path == null){
None
} else {
Some(richFile.path.split("/"))
}
}
def main(args: Array[String]) {
val richFile = RichFile("/home/cay/readme.txt")
val RichFile(r @ _*) = richFile
println(r)
}
}