Can I use @switch and Enumerations?
Can a switch register be used to match patterns in enums?
I tried
import scala.annotation.switch
object Foo extends Enumeration {
val First = Value
val Second = Value
val Third = Value
}
object Main {
def foo(x: Foo.Value) = (x: @switch) match {
case Foo.First => 1
case Foo.Second => 2
case Foo.Third => 3
}
}
but get the following warning (Scala 2.11.4):
warning: could not emit switch for @switch annotated match
def foo(x: Foo.Value) = (x: @switch) match {
Then I tried to define an enum in Java, since Java enum
is different from Scala Enumeration
. No luck yet.
@switch
Is pattern matching only available for primitive types?
source to share
To complete Regis' answer, in Scala In Depth, Joshua Suereth states that for Scala to optimize tableswitch optimization, the following conditions must be met:
- The corresponding value must be a known integer.
- The corresponding expression must be "simple". It cannot contain type checking if statements or extractors.
- The expression must also have an accessible value at compile time.
- There must be more than two case statements.
The Foo object does not meet any of the above criteria, although it is not subject to optimization by tableswitch.
source to share
The point of annotation switch
is to make sure your match is compiled into a JVM statement tableswitch
or lookupswitch
. These instructions only work on int, which means the annotation switch
will only have any effect on types that can safely fit into Int
. Value Int
, and Char
, Byte
, Short
and Boolean
. Also, the values ββyou are matching must be literal values ββ(as opposed to the values ββstored in val
). Given what Enumeration
is the pivot value, they are not annotation compatible switch
. The literal limitation actually means that it may not be possible to use this ennotation for Short
andByte
for purely syntactic reasons, since there is no support for literal shorts and bytes in scala: you have to use literal int along with a type type, as in 123: Byte
, but this is not accepted as a pattern. Thus, only Int
, Char
and Boolean
(usefulness of use @switch
for a boolean value is at least questionable) remains as valid types.
source to share