类型参数上的模式匹配T
引发未选中的警告
scala> def f[T](v: List[Any]): List[T] = v.collect { case x: T => x }
^
warning: abstract type pattern T is unchecked since it is eliminated by erasure
def f[T](v: List[Any]): List[T]
哪个可能会尝试用ClassTag
解决
scala> def f[T: scala.reflect.ClassTag](v: List[Any]): List[T] = v.collect { case x: T => x }
def f[T](v: List[Any])(implicit evidence$1: scala.reflect.ClassTag[T]): List[T]
解决了基于类的简单类型的警告
scala> f[String](List(42, "a"))
val res7: List[String] = List(a)
但是现在,即使对于在运行时擦除了组件的参数化类型的类型,未选中的警告也会被隐藏
f[List[String]](List(List(42)))
val res9: List[List[String]] = List(List(42)) // oops!
在后一种情况下,我们如何继续发出未经检查的警告?
Scala 3 用TypeTest
替换了ClassTag
,或者它的速记Typeable
,当我们尝试检查的不仅仅是一个类型的类组件时,它会发出警告
scala> def f[T: scala.reflect.Typeable](v: List[Any]): List[T] = v.collect { case x: T => x }
def f[T](v: List[Any])(implicit evidence$1: scala.reflect.Typeable[T]): List[T]
scala> f[String](List(42, "a"))
val res0: List[String] = List(a)
scala> f[List[String]](List(List(42)))
1 |f[List[String]](List(List(42)))
| ^
| the type test for List[String] cannot be checked at runtime
val res1: List[List[String]] = List(List(42))
正如更聪明的人所说
TypeTag
不再存在型式试验
ClassTag.unapply
不合理,不应使用相反,我们现在有
TypeTest
:lampepfl/dotty#7555