- type bounds
class Pair[T <: Comparable[T]](val first: T, val second: T) {
def smaller = if (first.compareTo(second) < 0) first else second //compareTo
}
class Pair[T](val first: T, val second: T) {
def replaceFirst(newFirst: T) = new Pair[T](newFirst, second)
}
def replaceFirst[R >: T](newFirst: R) = new Pair[R](newFirst, second)
- Implicit
class Pair[T](val first: T, val second: T)(implicit ev: T => Comparable[T]) {
def smaller = if (first.compareTo(second) < 0) first else second
...
}
smaller can be called by Pair[Int] even though Int is not comparable
class Pair[T : Ordering](val first: T, val second: T) {
def smaller(implicit ord: Ordering[T]) =
if (ord.compare(first, second) < 0) first else second
}
need to provide implicit parameter for smaller method.
- classtag to instantiate array of T correctly
def makePair[T : ClassTag](first: T, second: T) = {
val r = new Array[T](2); r(0) = first; r(1) = second; r
}
T <: Comparable[T] with Serializable with Cloneable
- variance
- covariant for return type
class Pair[+T](val first: T, val second: T)
T varies in the same direction of Pair
- contravariant for parameter type
trait Friend[-T] {
def befriend(someone: T)
}
T varies in the opposite direction of Friend.
class Pair[+T](val first: T, val second: T) {
def replaceFirst(newFirst: T) = new Pair[T](newFirst, second) // Error
}
workaround is
def replaceFirst[R >: T](newFirst: R) = new Pair[R](newFirst, second)