【问题标题】:Scala's "clean up" of type erasureScala 对类型擦除的“清理”
【发布时间】:2013-06-06 22:36:50
【问题描述】:
我刚刚开始研究 Scala,在Wikipedia page on Scala 中发现了以下令人费解的引语:
[Scala] 清理 [...] Java 中糟糕的设计决策(例如类型擦除...
我认为类型擦除是 Java 虚拟机施加的限制,所以鉴于 JVM 执行 Scala 代码,这是如何“清理”的?
我很欣赏 Scala 的设计者也为 JVM 做出了贡献,所以我很想知道他/Scala 团队是否增强了 Scala 编译器以携带丰富的运行时类型信息,从而“清理”类型擦除.是这样吗?
提前感谢您提供的任何见解。
【问题讨论】:
标签:
scala
compilation
jvm
type-erasure
【解决方案1】:
不幸的是,Scala 仍然必须在 JVM 中处理运行时的类型擦除。然而,一些关于泛型的事情已经被清理了:
- 类型参数是非可选的(没有
List,只有List<String>/List[String])
- 协变/逆变的语言支持
此外,为了处理 JVM 的限制,TypeTags(在 2.9 中为Manifests)可用于存储类型信息,否则这些信息会在运行时丢失。例如:
import scala.reflect.runtime.universe._
def foo[T : TypeTag](x: List[T]) = {
println(implicitly[TypeTag[T]].tpe)
}
这将打印列表元素的类型。如果 - 例如 - 你传递了一个空列表,就会丢失不可恢复的东西:
foo(List.empty[String])
// not distinguishable without TypeTags from
foo(List.empty[Int])
【解决方案2】:
嗯,这句话说的是“清理”,而不是“消除”。类型擦除仍然存在,它会咬你。
Scala 有Manifests。 Manifest 是一个对象,其中包含有关您的实际类型的信息。 Here is a nice answer 关于Manifests。