Сопоставление с образцом для типа Class [_]? - PullRequest
12 голосов
/ 22 сентября 2011

Я пытаюсь использовать сопоставление с шаблоном Scala в Java Class [_] (в контексте использования отражения Java от Scala), но получаю неожиданную ошибку. Ниже приведен «недоступный код» в строке с case 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")
  }
}

Есть идеи, почему это происходит?

Ответы [ 2 ]

16 голосов
/ 22 сентября 2011

Код работает должным образом, если вы меняете имена переменных в верхний регистр (или окружаете их обратными галочками в шаблоне):

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 Стабильные шаблоны идентификаторов

... Чтобы разрешить синтаксическое перекрытие с переменным шаблоном, стабильный шаблон идентификатора не может быть простым именем, начинающимся со строчной буквы письмо. Тем не менее, можно заключить такое имя переменной в обратные кавычки; затем он рассматривается как шаблон стабильного идентификатора.

См. этот вопрос для получения дополнительной информации.

7 голосов
/ 22 сентября 2011

При сопоставлении с образцом в каждом из этих двух случаев пытаются создать имена заполнителей вместо сопоставления типа класса, как и ожидалось.

Если вы начнете использовать верхний регистр, все будет в порядке

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
...