0

can anyone explain the behaviour of this snippet:

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

The Result is

match
noMatch

Why is there a difference when I change the val against the string literal ?

Volker
  • 35
  • 4
  • 2
    You are shadowing the variable `xx`, your first `Some(xx)` is not translated to `Some("2")` but to `Some(someVariable)`. – Ende Neu Dec 07 '15 at 09:29

1 Answers1

6

The expression case Some(xx) doesn't match against the value of xx which is in scope, but rather matches anything and binds that result to a new variable called xx, shadowing the outer definition.

If you want to match against the existing variable, either use backticks:

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

or rename the variable to start with an uppercase letter:

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: This is referred to as Stable Identifier Pattern defined in §8.1.5 in the Scala language specification

knutwalker
  • 5,924
  • 2
  • 22
  • 29