Почему сопоставление шаблонов в 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")

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

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

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

1 95

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

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