[关闭]
@amoszhou 2014-05-19T10:36:18.000000Z 字数 2593 阅读 1177

第十一章:操作符

scala课后习题


1.根据优先级规则,3 + 4 -> 5和3 -> 4 + 5是如何被求值的?

都是从左到右,貌似 3->4+5 会编译不过去。

2. BigInt类有一个pow方法,但没有用操作符字符。Scala类库的设计者为什么没有选用**(像Fortran那样)或者^(像Pascal那样)作为乘方操作符呢?

Scala中的操作符就是方法,其优先级是根据首字母来判断的,一般乘方的操作符是优于乘法操作的,如果使用*作为乘方的话,那么其优先级则与相同,而如果使用^的话,则优先级低于*操作。

3 实现Fraction类,支持+*/操作。支持约分,例如将15/-6变为-5/2。

  1. import scala.math.abs
  2. class Fraction(n: Int, d: Int) {
  3. private val num: Int = if (d == 0) 1 else n * sign(d) / gcd(n, d);
  4. private val den: Int = if (d == 0) 0 else d * sign(d) / gcd(n, d);
  5. override def toString = num + "/" + den
  6. def sign(a: Int) = if (a > 0) 1 else if (a < 0) -1 else 0
  7. def gcd(a: Int, b: Int): Int = if (b == 0) abs(a) else gcd(b, a % b)
  8. def +(other:Fraction):Fraction={
  9. newFrac((this.num * other.den) + (other.num * this.den),this.den * other.den)
  10. }
  11. def -(other:Fraction):Fraction={
  12. newFrac((this.num * other.den) - (other.num * this.den),this.den * other.den)
  13. }
  14. def *(other:Fraction):Fraction={
  15. newFrac(this.num * other.num,this.den * other.den)
  16. }
  17. def /(other:Fraction):Fraction={
  18. newFrac(this.num * other.den,this.den * other.num)
  19. }
  20. private def newFrac(a:Int,b:Int):Fraction={
  21. val x:Int = if (b == 0) 1 else a * sign(b) / gcd(a, b);
  22. val y:Int = if (b == 0) 0 else b * sign(b) / gcd(a, b);
  23. new Fraction(x,y)
  24. }
  25. }
  26. object Test extends App{
  27. val f = new Fraction(15,-6)
  28. val p = new Fraction(20,60)
  29. println(f)
  30. println(p)
  31. println(f + p)
  32. println(f - p)
  33. println(f * p)
  34. println(f / p)
  35. }

5. 提供操作符用于构造HTML表格。例如:Table() | "Java" | "Scala" || "Gosling" | "Odersky" || "JVM" | "JVM,.NET"应产出:<table><tr><td>Java</td></tr><td>Scala</td></tr><tr><td>Goling...

  1. class Table{
  2. private var s:String = ""
  3. def |(str:String):Table={
  4. s +="<td>" + str + "</td>"
  5. this
  6. }
  7. def ||(str:String):Table={
  8. s += "</tr><tr><td>" + str + "</td>"
  9. this
  10. }
  11. override def toString():String={
  12. "<table><tr>" + this.s + "</tr></table>"
  13. }
  14. }
  15. object Table{
  16. def apply():Table={
  17. new Table()
  18. }
  19. def main(args: Array[String]) {
  20. println(Table() | "Java" | "Scala" || "Gosling" | "Odersky" || "JVM" | "JVM,.NET")
  21. }
  22. }

9.为RichFile类定义unapply操作,提取文件路径,名称和扩展名。举例来说,文件/home/cay/readme.txt的路径为/home/cay,名称为readme,扩展名为txt

  1. class RichFile(val path:String){}
  2. object RichFile{
  3. def apply(path:String):RichFile={
  4. new RichFile(path)
  5. }
  6. def unapply(richFile:RichFile) = {
  7. if(richFile.path == null){
  8. None
  9. } else {
  10. val reg = "([/\\w+]+)/(\\w+)\\.(\\w+)".r
  11. val reg(r1,r2,r3) = richFile.path
  12. Some((r1,r2,r3))
  13. }
  14. }
  15. def main(args: Array[String]) {
  16. val richFile = RichFile("/home/cay/readme.txt")
  17. val RichFile(r1,r2,r3) = richFile
  18. println(r1)
  19. println(r2)
  20. println(r3)
  21. }
  22. }

10.为RichFile类定义一个unapplySeq,提取所有路径段。举例来说,对于/home/cay/readme.txt,你应该产出三个路径段的序列:home,cay和readme.txt

  1. class RichFile(val path:String){}
  2. object RichFile{
  3. def apply(path:String):RichFile={
  4. new RichFile(path)
  5. }
  6. def unapplySeq(richFile:RichFile):Option[Seq[String]]={
  7. if(richFile.path == null){
  8. None
  9. } else {
  10. Some(richFile.path.split("/"))
  11. }
  12. }
  13. def main(args: Array[String]) {
  14. val richFile = RichFile("/home/cay/readme.txt")
  15. val RichFile(r @ _*) = richFile
  16. println(r)
  17. }
  18. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注