2011-09-22 60 views
9

我想在Java Class [_]上使用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") 
    } 
} 

任何想法?

回答

15

代码工作,如果你改变的变量名大写(或在图案反引号包围他们)预期:

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。从specification

8.1.1可变图案

...一个可变图案x是一个简单的标识符,其与小写字母开始。它 匹配任何值,并将变量名称绑定到该值。

...

8.1.5稳定标识符模式

...要解决与可变图案的句法的重叠,一个稳定 标识符图案可能不是一个简单的名称开始与小写 字母。但是,可以在 反引号中附上这样的变量名称;那么它被视为一个稳定的标识符模式。

有关更多信息,请参见this question

+1

反引号是比我更好的解决办法:) – JaimeJorge

+0

真棒!非常感谢,特拉维斯。 – alphageek

7

在您的模式匹配上,这两种情况中的每一种都尝试创建占位符名称,而不是按照预期匹配类类型。

如果你在起始字符使用上的情况下,你会被罚款

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