Scala: проблема сопоставления с образцом с полностью определенными именами классов при параметризации - PullRequest
11 голосов
/ 14 сентября 2011

У меня небольшая проблема с сопоставлением с шаблоном объекта в Scala, когда он параметризован с полным именем класса.Это основано на Scala 2.9.0.1.Кто-нибудь знает, что не так с этим кодом?

scala> "foo" match {
 | case y : Seq[Integer] =>
 | case y : Seq[java.lang.Integer] =>
<console>:3: error: ']' expected but '.' found.
   case y : Seq[java.lang.Integer] =>

Почему работает первая версия, но последняя не работает?Кажется, проблема возникает, только когда для параметризации используется полное имя класса.

Ответы [ 2 ]

12 голосов
/ 14 сентября 2011

Из Спецификации языка Scala , раздел 8.1 Шаблоны, идентификатор после: должен быть тем, что упоминается как Шаблон типа, определенный в Разделе 8.2:

Типовые шаблоны состоят из типов, переменных типов и подстановочных знаков. Тип шаблон T имеет одну из следующих форм:

...

Параметризованный тип шаблона T [a (1),. , , , a (n)], где a (i) введите переменные шаблоны или символы подстановки _. Этот тип шаблона соответствует всем значения, которые соответствуют T для некоторой произвольной реализации типа переменные и подстановочные знаки. Тип границ или псевдонимов этих типов переменные определяются, как описано в (§8.3).

...

Шаблон переменной типа - это простой идентификатор, который начинается с строчная буква. Однако предопределенные псевдонимы примитивного типа unit, boolean, byte, short, char, int, long, float и double не являются классифицируется как тип переменных шаблонов.

Таким образом, синтаксически, вы не можете использовать полностью определенный класс в качестве шаблона переменной типа В ЭТОЙ ПОЗИЦИИ. Однако вы можете использовать псевдоним типа, так:

type JavaInt = java.lang.Integer
List(new java.lang.Integer(5)) match {
    case y: Seq[JavaInt] => 6
    case _ => 7
}

вернет 6, как и ожидалось. Проблема в том, что, как указывает Алан Берлисон, следующее также возвращает 6:

List("foobar") match {
    case y: Seq[JavaInt] => 6
    case _ => 7
}

потому что тип стирается. Вы можете увидеть это, запустив REPL или scalac с опцией -unchecked.

3 голосов
/ 14 сентября 2011

На самом деле ваш первый пример тоже не работает.Если вы запустите REPL с параметром -unchecked, вы увидите следующую ошибку:

предупреждение: не переменный аргумент типа Integer в шаблоне типа Seq [Integer] не проверяется, так как он удаляется при стирании1004 *

Таким образом, вы на самом деле не можете делать то, что пытаетесь сделать - во время выполнения нет никакой разницы между List [Integer] и List [AnythingElse], поэтому вы не можете сопоставить шаблонв теме.Вы можете сделать это с помощью манифеста, см. http://ofps.oreilly.com/titles/9780596155957/ScalasTypeSystem.html#Manifests и http://www.scala -blogs.org / 2008/10 / manifest-reified-types.html

...