抽象类型模式未经检查,因为它被擦除消除了。

27

请问有人可以告诉我如何避免下面代码块中的警告吗:

abstract class Foo[T <: Bar]{
  case class CaseClass[T <: Bar](t: T)
  def method1 = {
    case CaseClass(t: T) => println(t)
    csse _ => 
  }
}

这会导致编译器发出警告:
 abstract type pattern T is unchecked since it is eliminated by erasure
 case CaseClass(t: T) => println(t)
                   ^

第一行的 T <: Bar 是什么意思? - Kevin Meredith
иҝҷеҸӘжҳҜж„Ҹе‘ізқҖеҸӮж•°tзҡ„зұ»еһӢеҸ—еҲ°Tзҡ„дёҠз•ҢйҷҗеҲ¶гҖӮжҚўеҸҘиҜқиҜҙпјҢTжҳҜBarзҡ„еӯҗзұ»еһӢжҲ–Barжң¬иә«гҖӮ - Harshal Pandya
不,这意味着t的类型在运行时不能保证是T,因为JVM执行类型擦除(丢弃类型信息)。 - automorphic
2个回答

30
您可以使用ClassTag(或TypeTag):
import scala.reflect.ClassTag

abstract class Foo[T <: Bar : ClassTag]{
  ...
  val clazz = implicitly[ClassTag[T]].runtimeClass
  def method1 = {
    case CaseClass(t) if clazz.isInstance(t) => println(t) // you could use `t.asInstanceOf[T]`
    case _ => 
  }
}

2
这里的 classtag 是做什么用的? - Blankman
1
假设您在类参数签名中指的是ClassTag,它告诉编译器为该类创建一个隐式的ClassTag[T]参数,然后通过implicitly[ClassTag[T]]访问。abstract class Foo[T: ClassTag]abstract class Foo[T](implicit tag: ClassTag[T])的简写形式。 - WeaponsGrade

3

如果您希望使用trait(而不是使用其他解决方案所需的classabstract class),则可以使用另一种变体,如下所示:

import scala.reflect.{ClassTag, classTag}

trait Foo[B <: Bar] {
  implicit val classTagB: ClassTag[B] = classTag[B]
  ...
  def operate(barDescendant: B) =
    barDescendant match {
      case b: Bar if classTagB.runtimeClass.isInstance(b) =>
        ... //do something with value b which will be of type B
    }
}

1
谢谢。我需要在一个trait中使用这个,但是我无法完全理解隐式版本。干杯。 - AetherMass

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接