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

Scala 我可以使用@switch和枚举吗?,scala,enums,switch-statement,pattern-matching,scala-2.11,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

我可以使用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):

然后我尝试用Java定义枚举,因为Java的
enum
s不同于Scala的
enumeration
。还是不走运


@switch
模式匹配仅在基元类型上可用?

switch注释的要点是确保将匹配编译成
表开关
查找开关
JVM指令。这些指令仅适用于Int,这意味着
开关
注释仅对可以安全地装入
Int
的类型有效。意思是
Int
本身以及
Char
Byte
Short
Boolean
。此外,匹配的值必须是文字值(与存储在
val
中的值相反)。鉴于
枚举
是参考值,它们与
开关
注释不兼容。关于文字值的限制实际上意味着,出于纯粹的语法原因,
Short
Byte
可能无法使用此ennotation,因为scala中不支持文字短字符和字节:必须使用文字int和类型归属,如
123:Byte
,但这并不是一种模式。
因此,只剩下
Int
Char
Boolean
作为有效类型(至少可以说,对布尔值使用
@switch
的有用性是值得怀疑的)

以Scala深度完成Regis的答案,Joshua Suereth指出,Scala应用表开关优化必须满足以下条件:

  • 匹配的值必须是已知的整数
  • 匹配的表达式必须是“simple”。它不能包含任何类型检查、if语句或提取器
  • 表达式的值也必须在编译时可用
  • 应该有两个以上的案例陈述

  • Foo对象不符合上述任何标准,尽管它不是表开关优化的主题。

    尽管枚举上的Java开关大小写会导致
    表开关
    /
    查找开关
    。但是,是的,我的选择似乎是(1)编写Java,或者(2)如您所说,使用原语类型。这里的重要区别是Java枚举具有内置语言支持,而Scala枚举仅在标准库中定义
    warning: could not emit switch for @switch annotated match
      def foo(x: Foo.Value) = (x: @switch) match {