I found that when using pattern matching with alternatives (for strings), Scala accepts variables starting with upper case (in the example below, MyValue1
and MyValue2
), but not those starting with lower case (myValue1
, myValue2
). Is this a bug or a feature of Scala? I get this in version 2.8. If this is a feature, can anyone explain the rationale behind it? This is the code I used:
val myValue1 = "hello"
val myValue2 = "world"
val MyValue1 = "hello"
val MyValue2 = "world"
var x:String = "test"
x match {
case MyValue1 | MyValue2 => println ("first match")
case myValue1 | myValue2 => println ("second match")
}
On running, I get the following:
scala> val myValue1 = "hello"
myValue1: java.lang.String = hello
scala> val myValue2 = "world"
myValue2: java.lang.String = world
scala> val MyValue1 = "hello"
MyValue1: java.lang.String = hello
scala> val MyValue2 = "world"
MyValue2: java.lang.String = world
scala> var x:String = "test"
x: String = test
scala> x match {
| case MyValue1 | MyValue2 => println ("first match")
| case myValue1 | myValue2 => println ("second match")
| }
<console>:11: error: illegal variable in pattern alternative
case myValue1 | myValue2 => println ("second match")
^
<console>:11: error: illegal variable in pattern alternative
case myValue1 | myValue2 => println ("second match")
^
EDIT:
So it is indeed a feature and not a bug... Can anyone provide an example when this might be useful?
When I use:
x match {
case myValue1 => println ("match")
case _ =>
}
I get an unreachable code
warning on the last case, implying that the first one always matches.
This is not specific to patterns with alternatives, and it is not a bug. An identifier that begins with a lowercase letter in a pattern represents a new variable that will be bound if the pattern matches.
So, your example is equivalent to writing:
x match {
case MyValue1 | MyValue2 => println ("first match")
case y | z => println ("second match")
}
You can work around this by using backticks:
x match {
case MyValue1 | MyValue2 => println ("first match")
case `myValue1` | `myValue2` => println ("second match")
}