检查arg1是否为arg2实例的函数,如Scala中的isInstanceOf(a,A)

时间:2014-12-02 14:26:48

标签: class scala reflection

我一直试图想出一个函数来检查参数是否是在运行时给出的类型。

在以下示例中考虑函数is(“is of class”的缩写):

    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的新手,似乎无法正确应用它们。如何is实施所有println - 行以返回true

1 个答案:

答案 0 :(得分:0)

您正在检查 T,它将是AB伴随对象 - 它如果使用非案例类,可能更容易理解发生了什么。

在更正代码之后,你会发现它总是返回true,并警告说由于擦除而导致模式未被检查:

def is[TYPE](value: Any): Boolean = value match {
  case t: TYPE => true
  case _ => false
}

通常的做法是使用ClassTag作为模式:

def is[TYPE](value: Any)(implicit tag: ClassTag[TYPE]): Boolean = value match {
  case tag(_) => true
  case _ => false
}

请注意,这只会匹配运行时,已删除的类,因此您将获得泛型类型的惊人答案:

is[List[Int]](List("abc")) //true

如果您想要更通用的解决方案,可以查看Shapeless type-safe extractors