scala 中 ClassTag、TypeTag、ClassManifest、Manifest 和 上下文绑定的使用

如下两个函数定义是等价的

def max[T](a:T, b:T) (implicit cp : A[T]) {}
def max[T : A] (a:T, b:T){}

符号 [T : A] 是一个上下文绑定,它表示上述 max 函数需要一个类型为 A[T] 的隐式参数。

 

编译器会擦除泛型信息,为了获取泛型的类型信息元数据,Scala 引入 ClassTag、TypeTag、ClassManifest、Manifest 

来解决这个问题。其中 ClassTag 是 ClassManifest 升级版,TypeTag 是 Manifest 升级版。

 

先看下面的例子,[T: Ordering]是一个上下文绑定,通过  implicitly[Ordering[T]] 拿到这个绑定的隐式参数 ord,然后比较大小,

这个例子用到了标准库函数  def implicitly[T](implicit e: T): T = e,这个函数作用是从上下文中获取 类型 T 的隐式值

case class People(age: Int, name: String)

object People {
// 定义一个隐式变量 implicit val ord: Ordering[People] = new Ordering[People]() { override def compare(x: People, y: People): Int = x.age - y.age } } object ContextBound {
def max[T: Ordering](x: T, y: T): T = { val ord = implicitly[Ordering[T]] if (ord.gt(x, y)) x else y } def main(args: Array[String]): Unit = { println(max(People(10, "a"), People(20, "b"))) } }

输出:

People(20,b),这里通过隐士对象 ord 来比较大小

 

我们写 [T: ClassTag] ,意味着需要一个 ClassTag[T] 类型的隐式参数,通过这个隐式参数我们可以获取 T 的信息

 

posted on 2021-05-26 00:53  一直小飞猫  阅读(314)  评论(0编辑  收藏  举报

导航