【问题标题】:Why the Scala method isInstanceOf[T] is not working为什么 Scala 方法 isInstanceOf[T] 不起作用
【发布时间】:2020-04-18 11:12:30
【问题描述】:

为什么isInstanceOf[T] 方法没有按预期工作?

在下文中,我定义了一个hello 类和伴随对象。在 hello 对象中,我在代码行“hel.typetest[Int]”中测试了this.isInstanceOf[T],当T 类型为Int 时,为什么这是true

object hello {
  def main(args: Array[String]): Unit = {
    Console.println("main")
    val hel = new hello
    hel.typetest[Int]
  }
}

class hello {
  def typetest[T: ClassTag]: Unit = {
    Console.println(this.isInstanceOf[T])
    Console.println(this.getClass)
  }
}

输出:

main
true
class hello

【问题讨论】:

标签: scala generics reflection instanceof type-erasure


【解决方案1】:

因为type erasure(连同拳击)。 T 擦除为 Object,因此 this.isInstanceOf[T] 在字节码中变为 this.isInstanceOf[Object],这始终是正确的。

碰巧ClassTag 旨在避免这种情况,但您需要实际使用它而不是调用isInstanceOf

def typetest[T](implicit tag: ClassTag[T]): Unit = {
  Console.println(tag.runtimeClass.isInstance(this))
}

当存在ClassTag 时,还有一个特殊情况support 用于与T 进行模式匹配:

def typetest[T: ClassTag]: Unit = {
  Console.println(this match {
    case _: T => true
    case _ => false
  })
}

有人提议让is/asInstanceOf[T]ClassTag 也存在时正常工作,但是编译器内置了一些假设可以防止这种情况发生并且很难改变(如果我记得原因的话正确)。

【讨论】:

  • 只是补充一点:ClassTag 只匹配更高的类型。它与更高类型的参数类型不匹配。例如:valueToMatch match { case _: T => true case _ => false 如果 valueToMatch 是 List[Int],则无论 T 是 List[String] 还是 List[Int] 或任何其他类型的 List,如果 T 是 List,它将始终打印 true。
猜你喜欢
  • 1970-01-01
  • 2016-09-12
  • 2023-03-03
  • 1970-01-01
  • 2013-01-22
  • 2018-08-06
  • 2012-01-14
  • 2015-11-07
  • 2015-12-10
相关资源
最近更新 更多