2015-01-05 105 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枚舉純粹是在標準庫中定義的 –

相關問題