2015-01-05 71 views
3

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

我试图

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

但得到以下警告(斯卡拉2.11.4):

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

然后我试图定义Java中的枚举,而不是,因为Java的enum s为比Scala的不同Enumeration。仍然没有运气。

@switch模式匹配只适用于原始类型?

回答

1

要完成红塔答案,在斯卡拉的深入,约书亚Suereth指出以下条件必须符合斯卡拉适用桌面开关优化:

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

Foo对象与以上任何条件都不匹配,尽管它不是tableswitch优化的主题。

1

switch注释的目的是确保将您的匹配编译为tableswitchlookupswitch JVM指令。这些说明仅适用于整数,这意味着switch注释只对安全适合Int的类型有效。含义Int本身以及Char,Byte,ShortBoolean。另外,您匹配的值必须是文字值(与存储在val中的值相反)。鉴于Enumeration是参考值,它们与switch注释不兼容。关于字面值的限制实际上意味着可能没有办法使用这种内涵ShortByte,由于纯粹的语法原因,因为scala中不支持字面短语和字节:您必须使用文字int和类型在123: Byte归属,但这不被接受为一种模式。 这样只剩IntCharBoolean为有效类型(使用@switch一个布尔值的用处是值得怀疑的,至少可以说)

+0

尽管Java在枚举上的开关情况导致了“tableswitch”/“lookupswitch”。但是,是的,看起来我的选择似乎是(1)编写Java,或者(2)如您所说,使用基本类型。 –

+0

这里的重要区别在于Java枚举具有内置的语言支持,而Scala枚举纯粹是在标准库中定义的 –

相关问题