考虑:
trait Base
trait Derived extends Base
class Narrow[T<:Base](arg :T) {
val d = arg match {
case derived :Derived => Some(derived)
case _ => None
}
}
在先前版本的scala(2.11.8之前)中,我记得derived
的类型为T with Derived
。这有时会导致类型推断的意外行为,但提供了完整的信息。现在(在2.11.8中),derived
子句中的case
类型只是Derived
。这当然是一个简化的例子,但实际上我有一个接受T with Derived
的方法,我想知道是否可以安全地(并且没有编译器警告)获得对这样一个实例的引用?自然地,
case derived :Derived with T =>
生成有关未经检查(已删除)类型匹配的警告。
答案 0 :(得分:1)
case derived: Derived with T @unchecked
有效。当然,使用@unchecked
意味着您必须确保代码是安全的而不是编译器,但在这种情况下,我认为它与2.11.8之前一样安全(即感谢类型擦除客户端)可以传递实际上不是T
)的参数。
答案 1 :(得分:0)
由于模式匹配与泛型将在编译时被编译器删除,所有匹配子句将匹配超类:Derived
对于这种情况,也许TypeTag是更好的解决方案:
class Narrow[T <: Base](arg: T)(implicit typeTag: TypeTag[T]) {
val d = arg match {
case derived if typeTag.tpe =:= typeOf[Derived] => println("I am ")
case derived if typeTag.tpe <:< typeOf[Derived] => println("Hello")
case _ => println("world")
}
}
Derived
首先,实际类型:Derived
匹配,不带Derived
子类型Derived
子类类型(Derived with T
或T extends Derived
,缩小它),因为Derived
类型在子句1 中匹配,此子句与Derived
类型现在