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?

+3


source to share


2 answers


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.

+1


source


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.



+1


source







All Articles