如何绕过Scala上的类型擦除?或者,为什么不能获得集合的类型参数?在Scala上,一个可悲的事实是,如果您实例化一个List[Int],您可以验证您的实例是一个列表,并且可以验证它的任何单个元素是否是Int,但不能验证它是否是List[Int],这一点很容易验证:scala> List(1,2,3) match {
| case l : List[String] => println("A list of strings?!")
| case _ => println("Ok")
| }warning: there were unchecked warnings; re-run with -unchecked for details
A list of strings?!未选中的选项将指责直接归咎于类型擦除:scala> List(1,2,3) match {
| case l : List[String] => println("A list of strings?!")
| case _ => println("Ok")
| }<console>:6: warning: non variable type-argument String in type pattern is unchecked since it is eliminated by erasure
case l : List[String] => println("A list of strings?!")
^A list of strings?!为什么,我怎么才能避开它?
3 回答
杨魅力
TA贡献1811条经验 获得超6个赞
这个答案使用 Manifest-API,它在Scala2.10中被废弃。请参阅下面的答案,以获得更多最新解决方案。
scala.collection.immutable.ListInt.
object Registry {
import scala.reflect.Manifest
private var map= Map.empty[Any,(Manifest[_], Any)]
def register[T](name: Any, item: T)(implicit m: Manifest[T]) {
map = map.updated(name, m -> item)
}
def get[T](key:Any)(implicit m : Manifest[T]): Option[T] = {
map get key flatMap {
case (om, s) => if (om <:< m) Some(s.asInstanceOf[T]) else None
}
}}scala> Registry.register("a", List(1,2,3))scala> Registry.get[List[Int]]("a")res6: Option[List[Int]] = Some(List(1, 2, 3))scala
> Registry.get[List[String]]("a")res7: Option[List[String]] = NoneManifest
白猪掌柜的
TA贡献1893条经验 获得超10个赞
Typeable
scala> import shapeless.syntax.typeable._import shapeless.syntax.typeable._ scala> val l1 : Any = List(1,2,3)l1: Any = List(1, 2, 3)scala> l1.cast[List[String]]res0: Option[List[String]] = Nonescala > l1.cast[List[Int]]res1: Option[List[Int]] = Some(List(1, 2, 3))
castTypeable
添加回答
举报
0/150
提交
取消
