Возьмем следующую функцию:
def fMatch(s: String) = {
s match {
case "a" => println("It was a")
case _ => println("It was something else")
}
}
Этот шаблон хорошо сочетается:
scala> fMatch("a")
It was a
scala> fMatch("b")
It was something else
Что я хотел бы сделать, так это следующее:
def mMatch(s: String) = {
val target: String = "a"
s match {
case target => println("It was" + target)
case _ => println("It was something else")
}
}
Это дает следующую ошибку:
fMatch: (s: String)Unit
<console>:12: error: unreachable code
case _ => println("It was something else")
Я предполагаю, что это потому, что он думает, что цель - это на самом деле имя, которое вы хотели бы присвоить любому входу. Два вопроса:
Почему такое поведение? Разве нельзя просто искать существующие переменные в области видимости, которые имеют соответствующий тип, и использовать их в первую очередь, а если ни одна не найдена, то рассматривать цель как имя для сопоставления с образцом?
Есть ли обходной путь для этого? Есть ли способ сопоставить шаблон с переменными? В конечном итоге можно использовать большой оператор if, но регистр совпадений более элегантен.
scala
pattern-matching
match
Генри Хенринсон
источник
источник
Ответы:
Вам нужен стабильный идентификатор . В Scala они должны начинаться с заглавной буквы или заключаться в обратные кавычки.
Оба из них будут решениями вашей проблемы:
Чтобы избежать случайной ссылки на переменные, которые уже существовали во включающей области, я думаю, имеет смысл, что по умолчанию строчные шаблоны должны быть переменными, а не стабильными идентификаторами. Только когда вы видите что-то, начинающееся с верхнего регистра или наоборот, вам нужно знать, что оно исходит из окружающей области.
источник
target
это значение (val
), а не переменная (var
). Он не работает с переменными.Nil
, и я уверен, что это настоящая причина.this
в качестве стабильного идентификатора для сопоставления с ним шаблона, кажется, единственный способ использовать защиту равенства, напримерcase x if x == this =>
. Вероятно, синтаксическое ограничение, иначе он должен семантически работать хотя бы в пределахobject
s.