【发布时间】:2016-04-27 04:33:04
【问题描述】:
我们以这个为例:
import scala.reflect._
def get[T](list: List[Any])(implicit tag: ClassTag[T]) = {
list.flatMap {
case element: T => Some(element)
case _ => None
}
}
我可以使用 get() 从列表中获取 T 类型的值(例如,get[String](list) 将提供该列表中的所有字符串)。
现在,我了解到编译器会自动提供 ClassTag[String] 类型的值。我也知道ClassTag 是一个类型类,在幕后某处有一段代码写着implicitly[ClassTag[T]].getRuntimeClass() 或其他什么。
但如果是这样,我们怎么能在没有类标签的情况下进行模式匹配(在这种情况下我们无法区分擦除的类型)?我的意思是,它是如何实现的,如果我声明一个隐式参数(由编译器自动提供),我会得到一种行为,但如果我没有得到不同的行为?
【问题讨论】:
-
顺便说一句,你可以像
def get[T : ClassTag](list: List[Any]) = list collect { case element: T => element }这样让这段代码更简洁 -
是的,我知道,这样更明显的是
tag没有在方法中使用。似乎有点神奇的是,有可能添加一个隐式参数而不用它显式地做任何事情,但却得到与参数不存在时不同的行为。 -
是的,我明白你的问题,我自己也觉得它很有趣,我投了赞成票,我正在等待答案,但我猜编译器在这里做了一些事情。
-
Documentation 只是声明,如果你声明一个类型为
ClassTag的隐式参数((Weak)TypeTags 也是如此)编译器将为你提供一个。但是,一旦您进入该方法,并且可能有也可能没有 ClassTag 类型的隐式值可供使用,您将不会知道发生了什么。
标签: scala reflection