Опциональный литерал и переменная варианта

Может кто-нибудь объяснить поведение этого фрагмента:

def test = {
  val xt: Option[String] = Some("1")
  val xx: String = "2"
  xt match {
    case Some(xx) => println("match")
    case _ => println("no match")
  }
  xt match {
    case Some("2") => println("match")
    case _ => println("no match")
  }
}

Результат

match
noMatch

Почему есть разница, когда я меняю значение val на строковый литерал?

1 ответ

Решение

Выражение case Some(xx) не соответствует значению xx который находится в области видимости, но скорее соответствует чему-либо и связывает результат с новой переменной с именем xx, следя за внешним определением.

Если вы хотите сопоставить существующую переменную, используйте обратные галочки:

def test = {
  val xt: Option[String] = Some("1")
  val xx: String = "2"
  xt match {
    case Some(`xx`) => println("match")
    case _ => println("no match")
  }
  xt match {
    case Some("2") => println("match")
    case _ => println("no match")
  }
}

или переименуйте переменную, чтобы начать с заглавной буквы:

def test = {
  val xt: Option[String] = Some("1")
  val Xx: String = "2"
  xt match {
    case Some(Xx) => println("match")
    case _ => println("no match")
  }
  xt match {
    case Some("2") => println("match")
    case _ => println("no match")
  }
}

edit: это упоминается как шаблон стабильного идентификатора, определенный в §8.1.5 в спецификации языка Scala

Другие вопросы по тегам