我可以使用@switch 和枚举吗?

Can I use @switch and Enumerations?

我可以使用 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模式匹配只适用于原始类型?

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

为了完成 Regis 的回答,在深入了解 Scala 中,Joshua Suereth 指出 Scala 必须满足以下条件才能应用 tableswitch 优化:

  1. 匹配的值必须是已知整数。
  2. 匹配的表达式必须是“简单的”。它不能包含任何类型检查、if 语句或提取器。
  3. 表达式在编译时还必须有可用的值。
  4. 应该有两个以上的case语句。

Foo 对象不符合上述任何条件,尽管它不是 tableswitch 优化的主题。