2012-06-16 69 views
120

我不得不說我不明白Scala枚舉類。我可以從文檔中複製粘貼示例,但我不知道發生了什麼。瞭解scala枚舉

object WeekDay extends Enumeration { 
    type WeekDay = Value 
    val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value 
} 
import WeekDay._ 
  • 什麼意思type WeekDay = Value,爲什麼我必須寫?
  • 爲什麼是val Mon = Value?那有什麼意思?
  • 爲什麼我必須導入WeekDay 對象?並且,
  • 當我寫val day = WeekDay.Mon時,它爲什麼鍵入WeekDay.Value,而不是WeekDay
+2

我寫了一個關於scala枚舉和替代的小概述,你可能會覺得它很有用:pedrorijo.com/blog/scala-enums/ – pedrorijo91

回答

149

Enumeration性狀具有表示枚舉的單個元件類型成員Value(它實際上是一個內部類,但差異並不重要這裏)。

因此object WeekDay繼承該類型的成員。行type WeekDay = Value只是一個類型別名。它是有用的,因爲你import WeekDay._導入其他地方後,您可以使用類型,例如:

def isWorkingDay(d: WeekDay) = ! (d == Sat || d == Sun) 

取而代之的是,最小的版本也只是:

object WeekDay extends Enumeration { 
    val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value 
} 

,而你沒有已到導入object WeekDay的內容,但那麼您將需要使用類型WeekDay.Value並限定個別成員。因此,例如將成爲

def isWorkingDay(d: WeekDay.Value) = ! (d == WeekDay.Sat || d == WeekDay.Sun) 

第二個問題是關於val Mon, ... = Value意義。如果你不考慮Enumeration的實現,這確實很令人困惑。這不是一種類型的分配!而是調用同名,Value的受保護方法,該方法返回Value類型的具體實例。

恰巧,你可以用Scala編寫val a, b, c = foo,併爲每個值ab,並c方法foo將被一次又一次地叫。 Enumeration使用這個技巧增加一個內部計數器,以便每個值都是單獨的。

如果您打開Enumeration的Scala API文檔並單擊Visibility: All,您將看到該方法出現。

+2

謝謝,這很混亂,但我認爲它是正確的。我將使用密封的案例類,它似乎100%更容易。 –

+2

我個人更喜歡密封的案例課。稍微冗長一些,但少一些可變內部計數器等等。使用Scala 2.10,有一些想法可以使用宏更好地編寫枚舉(與Java不同,它不是一種語言結構,而僅僅是一個庫解決方案)。 –

+0

@ 0__請問爲什麼以及如何使用密封類來替換Scala中的枚舉? Scala的Enumeration有什麼問題嗎? – x1a0