2011-09-22 126 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