我需要在Classes上进行模式匹配。问题是,我有一些与Long匹配的问题。
我需要以同样的方式处理scala.Long和java.lang.Long,但为什么我需要在两种情况下都声明它们?
以下是一个例子:
def test(typ: Class[_]) {
typ match {
case q if q == classOf[Long] => println("scala long...")
}
}
val scalaLongField: java.reflect.Field = ......
val javaLongField: java.reflect.Field = ......
test(scalaLongField.getType) // prints "scala long..."
test(javaLongField.getType) // scala.MatchError: class java.lang.Long (of class java.lang.Class)
有没有一种方法可以在没有实例但只有类的情况下处理它们?
答案 0 :(得分:4)
它应该可以立即使用:
object LongTest {
def test(value: Any): Boolean = value match {
case l: Long => true
case _ => false
}
def run() {
println(test(1L))
println(test(new java.lang.Long(1L)))
}
}
LongTest.run() // true and true
我想要匹配类而不是实例,这对我来说并不明显。我不确定我明白你真正想要的是什么。喜欢这个?
object LongTest {
def test(clazz: Class[_]): Boolean =
clazz == classOf[Long] || clazz == classOf[java.lang.Long]
def run() {
println(test(1L.getClass))
println(test(new java.lang.Long(1L).getClass))
}
}
LongTest.run() // true and true
或作为模式匹配:
def test(clazz: Class[_]): Boolean = clazz match {
case q if q == classOf[Long] || q == classOf[java.lang.Long] => true
case _ => false
}
答案 1 :(得分:4)
原因是java.lang.Long
和Long
是不同的类。在Java中,java.lang.Long.class
和Long.TYPE
之间存在差异。同样,在Scala中,classOf[Long]
和classOf[java.lang.Long]
不同。
如果要对类进行模式匹配,可以为此创建帮助unapply
方法:
object ScalaLong {
// Internal helper:
private def matchClass[T](c: Class[_], as: Class[T]): Option[Class[T]] =
if (as.isAssignableFrom(c)) Some(as)
else None;
// Matches wrapped Long classes.
object LongObject {
def unapply(c: Class[_]): Option[Class[java.lang.Long]] =
matchClass(c, classOf[java.lang.Long]);
}
// Matches primitive long classes.
object LongPrim {
def unapply(c: Class[_]): Option[Class[Long]] =
matchClass(c, classOf[Long]);
}
// -- Test:
def check(clz: Class[_]) =
clz match {
case LongPrim(c) => println("Long primitive: " + c);
case LongObject(c) => println("Long object: " + c);
case _ => println("Other: " + clz);
}
class Example {
val l1: scala.Long = 1L;
val l2: java.lang.Long = 1L;
val l3: java.lang.Integer = 1;
}
def main(argv: Array[String]) {
for(name <- Seq("l1", "l2", "l3"))
check(classOf[Example].getMethod(name).getReturnType());
}
}
通常,您必须单独处理classOf[Long]
和classOf[java.lang.Long]
。也许,如果你描述了你需要做什么,我们可以为你的特定任务找到更好的解决方案。