《快学Scala》第18章习题参考解答(高级类型)

来源:互联网 发布:双敏主板上的网络精灵 编辑:程序博客网 时间:2024/05/19 20:57

第一题

  package p1{    class Bug{      private var pos: Int = 0      private var direct: Int = 1      def move(p: Int) = {        this.pos += p * direct        this      }      def show() = {        print(this.pos + " ")        this      }      def turn() = {        this.direct *= -1        this      }    }    object Main extends App {      val bugsy = new Bug()      bugsy.move(4).show().move(6).show().turn().move(5).show()    }  }


第二题

  package p2{    object Show    object Then    object Around    class Bug{      private var pos: Int = 0      private var direct: Int = 1      def move(p: Int) = {        this.pos += p * direct        this      }      def turn(obj: Around.type) = {        this.direct *= -1        this      }      def and(obj: Show.type) = {      print(this.pos + " ")        this      }      def and(obj: Then.type) = this}    object Main extends App{      val bugsy: Bug = new Bug()      bugsy move 4 and Show and Then move 6 and Show turn Around move 5 and Show    }  }


第三题

  package p3{    object Title    object Author    class Document {      var title: String = _      var author: String = _      private var useNextArgAs: Any = null      def set(obj: Title.type): this.type = {        useNextArgAs = obj        this      }      def set(obj: Author.type): this.type = {        useNextArgAs = obj        this      }      def to(arg: String): this.type = {        if(useNextArgAs == Title) title = arg        else if(useNextArgAs == Author) author = arg        this      }      override def toString = "Title: " + title + ", author: " + author;    }    class Book extends Document{      def addChapter(chapter: String) = {        this      }    }    object Main extends App{      val book = new Book()      book set Title to "Scala for the Impatient" set Author to "Cay Horstmann"      println(book)    }  }


第四题

  package p4{  import scala.collection.mutable.ArrayBuffer    class Network {      // 参考 5.9节      outer =>      class Member(val name: String) {        val contacts = new ArrayBuffer[Member]        override def equals(other: Any): Boolean = {          other match {            // 参考 “路径” 章节,一个网络对应的Member的路径是outer.Member            // case self: Network.this.Member => true // 这个ok            // case self: outer.Member => true  // 这个ok            case self: Member => true // 深入理解路径            case _ => false          }        }      }      private val members = new ArrayBuffer[Member]      def join(name: String) = {        val m = new Member(name)        members += m        m      }    }    object Main extends App{      val chatter = new Network      val myFace = new Network      val fred = chatter.join("Fred")      val barney = myFace.join("Barney")      var jiexray = chatter.join("jiexray")      println(fred equals barney)      println(fred equals jiexray)    }  }


第五题

  package p5{    import scala.collection.mutable.ArrayBuffer    import scala.language.existentials    class Network {      class Member(val name: String) {        val contacts = new ArrayBuffer[Member]      }      private val members = new ArrayBuffer[Member]      def join(name: String) = {        val m = new Member(name)        members += m        m      }    }    object Main extends App {      type NetworkMember = n.Member forSome{val n: Network}      def process(m1: NetworkMember, m2: NetworkMember) = (m1, m2)      val chatter = new Network      val myFace = new Network      val fred = chatter.join("Fred")      val barney = myFace.join("Barney")      var jiexray = chatter.join("jiexray")      process(fred, barney)      process(fred, jiexray)    }    /*      解释:This is because for `process`, there's no relation       between the two different variables `n` in the type alias `NetworkMember`.      thanks: https://github.com/asarkar/scala-impatient/blob/master/src/main/scala/name/abhijitsarkar/scala/scalaimpatient/types/Network.scala    */  }


第六题

  package p6{    import scala.math._  object Main extends App{    def find(sortedArr: Array[Int], num: Int): Int Either Int = {        var distance = Int.MaxValue        var ans = 0        for(i <- 0 until sortedArr.length){          if(abs(sortedArr(i) - num) >= distance){            if(sortedArr(ans) == num) return Left(ans)            else return Right(ans)          }else{            ans = i            distance = abs(sortedArr(i) - num)          }        }        // not find return last index        if(sortedArr(ans) == num) return Left(ans)        else return Right(ans)      }      def get(res: Either[Int, Int]) = res match {        case Left(v) => println("find: " + v)         case Right(v) => println("find most reached: " + v)      }      val arr = Array(1,3,4,15,16,27,38)      val res1 = find(arr, 15)      get(res1)      val res2 = find(arr, 10)      get(res2)      val res3 = find(arr, 40)      get(res3)    }  }


第七题

  package p7 {    import scala.language.reflectiveCalls    object Main extends App{      def invoke[T <: {def close(): Unit}](target: T, fun: (T) => Unit) {        try{          fun(target)        } catch{          case ex: Exception => target.close; ex.printStackTrace        }finally{          target.close        }       }      object Test1{        def close(){          println("Test1 is closed")        }      }      object Test2{      }      def func(arg: Test1.type){        println("Test is operated")      }      def func1(arg: Test2.type){        println("Test2 is operated")      }      def func2(arg: {def close(): Unit}) {        println("Test is operated by func2")      }      invoke(Test1, func)      invoke(Test1, func2)      // Test2 cannot match type parameter T      // invoke(Test2, func1)    }  }


第八题

  package p8{    import scala.language.reflectiveCalls    object Main extends App {      def printValues(f: {def apply(n: Int):Int}, from: Int, to: Int) {        for(i <- from to `to`) print(f(i) + " ")        print("\n")      }      def printValues2(f: (Int) => (Int), from: Int, to: Int) {        for(i <- from to `to`) print(f(i) + " ")        print("\n")      }      printValues2((x: Int) => x * x, 3, 6)      printValues(Array(1,1,2,3,5,8,13,21,34,55), 3, 6)    }    /* more information:    https://stackoverflow.com/questions/45049928/using-structural-type-in-scala-occurs-nosuchmethodexception    */  }


第九题

  package p9{    /*      Ch18.scala:300: error: illegal inheritance; self-type ch18.p9.Meters does not conform to ch18.p9.Dim[ch18.p9.Seconds]'s selftype ch18.p9.Dim[ch18.p9.Seconds] with ch18.p9.Seconds    class Meters(v: Double) extends Dim[Seconds](v, "m"){                                    ^one error found    */    abstract class Dim[T](val value: Double, val name: String){      this: T =>       protected def create(v: Double): T      def +(other: Dim[T]) = create(value + other.value)      override def toString = value + " " + name;    }    class Seconds(v: Double) extends Dim[Seconds](v, "s"){      override val value = v      override def create(v: Double) = new Seconds(v)    }    // class Meters(v: Double) extends Dim[Seconds](v, "m"){    //   override def create(v: Double) = new Seconds(v)    // }    object Main extends App {      val s1 = new Seconds(10)      val s2 = new Seconds(10)      // val m = new Meters(10)      // println(s1 + m)      println(s1 + s2)    }  }


第十题

看不懂啊再见

原创粉丝点击