《快学Scala》第17章习题参考解答(类型参数)

第一题

package p1{
  class Pair[T, S](val first: T, val second: S){
    def swap() = {
      new Pair[S, T](second, first)
    }
    override def toString = "(" + first + ", " + second + ")"
  }

  object Main extends App{
    val p1 = new Pair(13126, "xia")
    val p2 = p1.swap
    println(p2)
  }
}

第二题

package p2{
  class Pair[T](var first: T, var second: T){
    def swap {
      val tmp = first
      first = second
      second = tmp
    }

    override def toString = "(" + first + ", " + second + ")"
  }

  object Main extends App{
    val p1 = new Pair(13126, "xia")
    p1.swap
    println(p1)
  }
}

第三题

package p3{
  class Pair[T, S](val first: T, val second: S){
    override def toString = "(" + first + ", " + second + ")"
  }

  object Main extends App{
    def swap[T, S](p: Pair[T, S]) = {
      new Pair(p.second, p.first)
    }

    val p1 = new Pair(13126, "xia")
    println(swap(p1))
  }
}

第四题

package p4{
  class Pair[T](val first: T, val second: T) {
    def replaceFirst(newFirst: T) = new Pair[T](newFirst, second)
    override def toString = "(" + first + ", " + second + ")"
    def replaceFirst2[R >: T](newFirst: R) = new Pair[R](newFirst, second)
  }

  class Person(val name: String, val age: Int){
    override def toString = name + " " + age
  }

  class Student(val school: String, name: String, age: Int) extends Person(name, age){
    override def toString = super.toString + " " + school
  }

  object Main extends App{
    val p1 = new Pair(new Person("xia", 13126), new Person("zhang", 13126))
    val p2 = p1.replaceFirst(new Student("nankai", "wang", 13126))
    println(p2)

    // val p3 = new Pair(new Student("nankai", "xia", 13126), new Student("nankai", "zhang", 13126))
    // val p4 = p3.replaceFirst(new Person("wang", 13126))

    val p3 = new Pair(new Student("nankai", "xia", 13126), new Student("nankai", "zhang", 13126))
    val p4 = p3.replaceFirst2(new Person("wang", 13126))
    println(p4)
  }

  /*
    1. Student是Person的子类,newfirst:Student可以转化成Person(子->父)
    2. p3, p4会导致编译错误,这是是因为newFirst:Person无法转化为Student(父->子)
    3. replaceFirst2函数犹豫定义了新的类型变量下界,second:student转化为Person(子->父)
  */
}

第五题

package p5{
  /*
    1. RichInt是为了丰富Int,而不是为了取代Int。
    2. Int可以自动转化为RichInt,一下来自Int的scaladoc
       There is an implicit conversion from scala.Int => scala.runtime.RichInt which provides useful non-primitive operations.
    3. 使用视图定界可以将Comparable[Int]转化为Comparable[RichInt]
  */
}


第六题

package p6{
  object Main extends App{
    def middle[T](lst: Iterable[T]): T = {
      val l = lst.toList
      l(lst.size / 2)
    }

    println(middle("World"))
  }
}

第七题

package p7{
  /*
    - foldLeft:foldLeft[B](z: B)(op: (B, A) ⇒ B): B
    - 在函数参数中(op: (B, A) ⇒ B为函数参数),型变是反转过来的,所以此时
      op函数参数的参数部分(B,A)是协变点。所以此时A是协变。
    - 同样的道理,grouped(size: Int): Iterator[Iterable[A]]
    - foreach(f: (A) ⇒ Unit): Unit 都应该是协变点。
  */
}

第八题

package p8{
  // class Pair[T](var first: T, var second: T){
  //   def replaceFirst[R >: T](newFirst: R) {first = newFirst}
  // }

  /*
    - 由于Pair没有型变,所以Pair[T]和Pair[R]没有任何关系。Pair[T]无法变成Pair[R],
      若要完成上述转变,需要Pair[T]是Pair[R]的子类,需要对Pair使用协变。
  */
}


第九题

package p9{
  import scala.math._
  // 此处T为协变,而函数repalceFirst中T为逆变点。
  class Pair[+T](val first: T, val second: T){
    // T is a covariance type. So an invariance R is introduced.
    def replaceFirst[R >: T](newFirst: R) = {
      new Pair(newFirst, second)
    }

    override def toString = "(" + first + ", " + second + ")"
  }

  class NastyDoublePair(first: Double, second: Double) extends Pair[Double](first, second){
    override def replaceFirst[R >: Double](newFirst: R) = {
      new Pair(newFirst, second)
    }
  }

  object Main extends App{
    // T为逆变,Pair[Any]是Pair[Double]的子类,Pair[Double]无法转化为Pair[Any]
    // val p: Pair[Any] = new NastyDoublePair(10, 20)
    val p: Pair[Double] = new NastyDoublePair(10, 20)

    //函数需要Double或者其父类。而String不是Double的父类。
    // println(p.replaceFirst("Hello"))
    println(p.replaceFirst(10))
  }
}

第十题

package p10{
  class Pair[S, T](var first: S, var second: T){
    def swap(implicit ev1: T =:= S, ev2: S =:= T){
      var tmp = first
      first = second
      second = tmp
    }

    override def toString = "(" + first + ", " + second + ")"
  }

  object Main extends App{
    val p1 = new Pair(10, 11)
    p1.swap
    println(p1)

    // val p2 = new Pair(10, "Hello")
    // println(p2.swap)	
}







评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值