我试图在Java类上使用Scala模式匹配[_](在使用Scala的Java反射的上下文中),但我得到了一些意想不到的错误。下面给出了大小写为jLong
的行中的"不可达代码"def foo[T](paramType: Class[_]): Unit = {
val jInteger = classOf[java.lang.Integer]
val jLong = classOf[java.lang.Long]
paramType match {
case jInteger => println("int")
case jLong => println("long")
}
}
知道为什么会这样吗?
如果您将变量名更改为大写(或在模式中使用反引号将其括起来),则代码将按预期工作:
scala> def foo[T](paramType: Class[_]): Unit = {
| val jInteger = classOf[java.lang.Integer]
| val jLong = classOf[java.lang.Long]
| paramType match {
| case `jInteger` => println("int")
| case `jLong` => println("long")
| }
| }
foo: [T](paramType: Class[_])Unit
scala> foo(classOf[java.lang.Integer])
int
在您的代码中,第一个模式中的jInteger
是一个新变量—它不是来自周围作用域的jInteger
。来自规范:
8.1.1变量模式
…变量模式x是一个简单的标识符,以小写字母开头。它匹配任何值,并将变量名绑定到该值。
…
8.1.5稳定标识符模式
…为了解决语法上的重叠,使用了一个可变模式,一个稳定的标识符模式可能不是以小写字母开头的简单名称信。但是,可以将这样的变量名包含在反引用;然后将其视为稳定的标识符模式。
在模式匹配中,这两种情况中的每一种都尝试创建占位符名称,而不是像预期的那样匹配类类型。
如果你在开始字符中使用大写字母,你就可以了
def foo[T](paramType: Class[_]): Unit = {
val JInteger = classOf[Int]
val JLong = classOf[Long]
paramType match {
case JInteger => println("int")
case JLong => println("long")
}
}
scala> foo(1.getClass)
int
JMPL是一个简单的java库,它可以模拟一些模式匹配的特性,使用java 8的特性。
matches(data).as(
Integer.class, i -> { System.out.println(i * i); },
Byte.class, b -> { System.out.println(b * b); },
Long.class, l -> { System.out.println(l * l); },
String.class, s -> { System.out.println(s * s); },
Null.class, () -> { System.out.println("Null value "); },
Else.class, () -> { System.out.println("Default value: " + data); }
);