如何将已擦除类型缩小(强制转换)为scala中的交集类型?

时间:2017-03-10 08:00:22

标签: scala casting pattern-matching

考虑:

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 =>

生成有关未经检查(已删除)类型匹配的警告。

2 个答案:

答案 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")
  }
}
  1. 仅匹配类型:Derived首先,实际类型:Derived匹配,不带Derived子类型
  2. 匹配Derived子类类型(Derived with TT extends Derived,缩小它),因为Derived类型在子句1 中匹配,此子句与Derived类型现在
  3. 不匹配
  4. 匹配其他课程。