我可以使用@switch和Enumerations吗?

时间:2015-01-05 01:53:34

标签: scala enums switch-statement pattern-matching scala-2.11

我可以在枚举上使用switch-case进行模式匹配吗?

我试过

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

但得到以下警告(Scala 2.11.4):

warning: could not emit switch for @switch annotated match
  def foo(x: Foo.Value) = (x: @switch) match {

然后我尝试用Java定义枚举,因为Java的enum与Scala的Enumeration不同。仍然没有运气。

@switch模式匹配仅在原始类型上可用吗?

2 个答案:

答案 0 :(得分:1)

switch注释的要点是确保将匹配编译为tableswitchlookupswitch JVM指令。这些说明仅适用于整数,这意味着switch注释只会对可以安全地适合Int的类型产生任何影响。含义Int本身以及CharByteShortBoolean。此外,您匹配的值必须是文字值(而不是存储在val中的值)。鉴于Enumeration是参考值,它们与switch注释不兼容。关于文字值的限制实际上意味着可能无法使用此注释ShortByte,纯粹出于语法原因,因为scala中不支持文字短路和字节:你必须使用文字int以及123: Byte中的类型归属,但这不作为模式接受。 因此,只留下IntCharBoolean作为有效类型(使用@switch作为布尔值的用处可疑至少可以说)

答案 1 :(得分:1)

要完成Regis的答案,在Scala In Depth中,Joshua Suereth声明Scala应用tableswitch优化时必须满足以下条件:

  1. 匹配的值必须是已知的整数。
  2. 匹配的表达式必须是“简单的”。它不能包含任何类型检查,if语句或提取器。
  3. 表达式在编译时也必须具有其值。
  4. 应该有两个以上的个案陈述。
  5. Foo对象与上述任何条件都不匹配,但它不是tableswitch优化的主题。