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

xiaoxiao2021-02-28  76

第一题

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

转载请注明原文地址: https://www.6miu.com/read-69051.html

最新回复(0)