第一题
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)
}