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

第一题

  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)
    }
  }


第十题

看不懂啊再见

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值