我一直试图想出一个函数来检查参数是否是在运行时给出的类型。
在以下示例中考虑函数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
?
答案 0 :(得分:0)
您正在检查值 T
,它将是A
或B
的伴随对象 - 它如果使用非案例类,可能更容易理解发生了什么。
在更正代码之后,你会发现它总是返回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