Class 函数,用于检查arg1是否是arg2的实例,如Scala中的isInstanceOf(a,a)

Class 函数,用于检查arg1是否是arg2的实例,如Scala中的isInstanceOf(a,a),class,scala,reflection,Class,Scala,Reflection,我一直在尝试设计一个函数来检查参数是否属于运行时给定的类型 在以下示例中,考虑函数是类的缩写: object TestClass { abstract class P() case class A() extends P case class B() extends P // ... case class Z() extends P def is[VALUE,TYPE](value:VALU

我一直在尝试设计一个函数来检查参数是否属于运行时给定的类型

在以下示例中,考虑函数是类的缩写:

    object TestClass {
        abstract class P()
        case class A() extends P
        case class B() extends P
        // ...
        case class Z() extends P

        def is[VALUE,TYPE](value:VALUE, T:TYPE): Boolean = {
            value match {
                case T => true
                case _ => false
            }
        }

        def main(args: Array[String]) {
            val a = new A()
            val b = new B()

            println(a.isInstanceOf[A]) // true
            println(is(a, A)) // false
            println(is(b, B)) // false
        }
    }

我已经读过ClassTag和getClass,但我对Scala是新手,似乎无法正确应用它们。如何实现所有println行返回true?

您正在检查值T,它将是A或B的伴生对象-如果使用非case类,可能更容易理解发生了什么

更正代码后,您会发现它总是返回true,并警告由于擦除,该模式未被选中:

def is[TYPE](value: Any): Boolean = value match {
  case t: TYPE => true
  case _ => false
}
通常的解决方法是使用类标记作为模式:

def is[TYPE](value: Any)(implicit tag: ClassTag[TYPE]): Boolean = value match {
  case tag(_) => true
  case _ => false
}
请注意,这将只匹配运行时已擦除的类,因此您将得到泛型类型的令人惊讶的答案:

is[List[Int]](List("abc")) //true
如果你想要一个更一般的解决方案,你可能想看看