Альтернативные случаи Scala соответствуют синтаксису с другим типом извлеченного значения - PullRequest
3 голосов
/ 18 августа 2011
object NoSense {
   def main(args: Array[String]) {
      val value = "true" match {
         case value @ (IntValue(_) | BooleanValue(_)) => value
      }
      require(value == true)
   }
}

class Value[T](val regex: Regex, convent: String => T) {
   def unapply(value: String): Option[T] = value match {
      case regex(value, _*) => Some(convent(value))
      case _ => None
   }
}
object IntValue extends Value[Int]("[0-9]+".r, _.toInt)
object BooleanValue extends Value[Boolean]("((true)|(false))".r, _.toBoolean)

Сбой require в методе main.
но с этим все в порядке

def main(args: Array[String]) {
      val value = "true" match {
         case IntValue(value) => value
         case BooleanValue(value) => value
      }
      require(value == true)
   }

Является ли это ограничением самого языка скала или я поступаю неправильно

1 Ответ

8 голосов
/ 18 августа 2011

Это ... и то и другое.

Вы можете посмотреть, как ведет себя механизм связывания, в спецификации Scala §8.1.3.Он говорит, что в шаблоне x@p:

тип переменной x - это статический тип T шаблона p.

В вашем случае шаблон p - это IntValue(_) | BooleanValue(_).Так как IntValue и BooleanValue unapply-методы оба требуют String, статический тип вашего паттерна String, таким образом, тип x равен String.

Во втором случае, значение извлекается из BooleanValue и имеет правильный тип.

К сожалению, scala не поддерживает альтернативные шаблоны экстракторов, поэтому вы должны придерживаться своей второй версии.

...