Volker
Volker

Reputation: 35

Option literal vs. Option variable

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 ?

Upvotes: 0

Views: 241

Answers (1)

knutwalker
knutwalker

Reputation: 5974

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

Upvotes: 6

Related Questions