第十一章:操作符

第十一章:操作符

标签(空格分隔): 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”应产出:"this } def ||(str:String):Table={ s += ""this } overridedef toString():String={ "
Java
Scala
Goling...
class Table{

     private var s:String = ""

    def |(str:String):Table={
        s +="
" + str + "
" + str + "
" + this.s + "
" } } 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)
  }
}

你可能感兴趣的:(快学scala)