Почему совпадение шаблонов в Scala не работает с переменными?

Возьмем следующую функцию:

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")

Я предполагаю, что это происходит потому, что он думает, что цель - это имя, которое вы хотите назначить независимо от того, что вводится. Два вопроса:

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

  • Есть ли обходной путь для этого? Любой способ сопоставления шаблонов с переменными? В конечном счете можно было бы использовать большой оператор if, но пример соответствия более изящный.

Ответ 1

То, что вы ищете, это стабильный идентификатор. В Scala они должны начинаться с заглавной буквы или быть окружены обратными окнами.

Оба из них будут решением вашей проблемы:

def mMatch(s: String) = {
    val target: String = "a"
    s match {
        case `target` => println("It was" + target)
        case _ => println("It was something else")
    }
}

def mMatch2(s: String) = {
    val Target: String = "a"
    s match {
        case Target => println("It was" + Target)
        case _ => println("It was something else")
    }
}

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