Scala Type Parameters 1
类型参数
-
表现形式:在名称后面以方括号表示,
Array[T]
-
何处使用
-
class 中,用于定义变量、入参、返回值
class Pair[T, S](val first: T, val second: S) // scala 可自动推断具体的类型 val p = new Pair(42, "String") // Pair[Int, String]
-
函数、方法
def getMiddle[T](a: Array[T]) = a(a.length / 2)
-
-
类型边界
-
上边界
T <: UpperBound
// 比较大小 class Pair[T](val first: T, val second: T) { def smaller = if (first.compareTo(second) < 0) first else second }
无法确定 first 是否存在
compareTo
方法,所以必须添加约束,fist 必须是Comparable
的子类型,即需要添加上边界class Pair[T <: Comparable[T]](val first: T, val second: T) { def smaller = if (first.compareTo(second) < 0) first else second }
-
下边界
T >: LowerBound
// 替换第一个元素 class Pair[T](val first: T, val second: T) { def replaceFirst(newFirst: T) = new Pair[T](newFirst, second) }
替换第一个元素为 T 的父类 R,那么返回类型是什么? 如果需要返回 R,则需要添加约束,即需要下边界;否则返回的类型为 Any
// 返回类型自动推断为 new Pair[R] def replaceFirst[R >: T](newFirst: R) = new Pair(newFirst, second)
-
上下文边界
T : ContextBound
Scala 2.8 对
Array
进行了更新优化,使用隐式转换和 manifest 将数组整合为 Scala 的集合库def tabulate[T](len: Int, f: Int => T)(implicitm: ClassManifest[T]) = { val xs = new Array[T](len) for(i <- 0 until len) xs(i) = f(i) xs } // 简化后 def tabulate[T: ClassManifest](len: Int, f: Int => T) = { val xs = new Array[T](len) for(i <- 0 until len) xs(i) = f(i) xs }
-
ClassTag
, 指定运行时的类型,如Array[Int]
在运行时想指定为 int[]import scala.reflect._ def makePair[T : ClassTag](first: T, second: T) = { val r = new Array[T](2); r(0) = first; r(1) = second; r } makePair(4, 9) // 实际调用 makePair(4, 9)(classTag) // new 操作,即 ClassTag[Int] 构建原始类型数组 int[2] classTag.newArray
-
-
多个边界
- 可同时添加上界和下界
T >: Lower <: Upper
- 不可添加多个上界或多个下届,但可实现多个
trait
,T <: Comparable[T] with Serializable with Cloneable
- 可指定多个上下文边界
T : Ordering : ClassTag
- 可同时添加上界和下界
-
-
类型约束
- 测试是否相等
T =:= U
- 测试是否为子类
T <:< U
- 测试是否可转换
T => U
要添加该约束,需添加隐式参数
// 约束类 class Pair[T](val first: T, val second: T)(implicit ev: T <:< Comparable[T]) // 约束方法调用,只有类型满足才能调用成功,否则报错 class Pair[T](val first: T, val second: T) { def smaller(implicit ev: T <:< Ordered[T]) = if (first < second) first else second } // 便于类型推断 def firstLast[A, C <: Iterable[A]](it: C) = (it.head, it.last) // 无法推断类型 A firstLast(List(1, 2, 3)) // [Nothing, List[Int]] // 添加约束关系 def firstLast[A, C](it: C)(implicit ev: C <:< Iterable[A]) = (it.head, it.last)
- 测试是否相等