即使尤瓦的回答是正確的解決方案將工作,使用Enumeration
編碼附加屬性不建議。通過使用name
字段中爲Value
是你正在失去建立在從String
經由.withName
方法來重構枚舉值實例Enumeration
類的能力的編碼類型作爲"Valid"
或"Not Valid"
(或任何其他分類):
// result will be always `a` for "Valid" and `b` for "Not Valid"
// it will throw an NoSuchElementException for any other string
MyEnum.withName(someString)
簡單地說,當你只是錯誤地使用name
字段來分類枚舉值實例時。如果這不是你的代碼中的問題,那麼你是一個幸運的人,但無論如何都要非常精確地記錄錯誤使用。
Enumeration
是爲了表達簡單的值,它有一個索引,可以有很好的人類可讀的名稱。就是這樣,不多也不少。
經驗法則是,當你有一個需要另一個字段的枚舉時,最好使用密封層次結構case objects
或case classes
進行建模。類似的東西(只爲您的具體情況爲例):
// Hierarchy is sealed, thus you will get can pattern match with check for exhaustiveness
sealed trait MyEnum {
def id: Int
def name: String
def valid: Boolean
}
// Helper case class, which allows to not define
private case class Value(id: Int, name: String, valid: Boolean) extends MyEnum
object MyEnum {
// Your values
val A: MyEnum = Value(0, "My A", true)
val B: MyEnum = Value(1, "My B", true)
val C: MyEnum = Value(0, "My A", false)
val D: MyEnum = Value(1, "My B", false)
// Re-implementation of methods contained in Enumeration, pick what you need
val values: Seq[MyEnum] = Seq(A, B, C, D)
// You can implement your own semantics, e.g. no Exception rather Option
def withName(name: String): Option[MyEnum] = values.find(_.name == name)
// Methods already for your example
val valids: Seq[MyEnum] = values.filter(_.valid)
// Or with randomization build in to enum
def randomValid: MyEnum = valids(util.Random.nextInt(valids.length))
}
此外,你會得到更多的類型安全:
// More type safety, fn simple does not compile
def fn(value: MyEnum) = value match {
case MyEnum.A => true
}
<console>:14: warning: match may not be exhaustive.
It would fail on the following input: Value(_, _, _)
def fn(value: MyEnum) = value match {
^
fn: (value: MyEnum)Boolean
你milage可能會有所不同,因爲在斯卡拉寫一個枚舉可能性幾乎無盡:)在我的例子中,我只展示了許多可能的實現中的一種。如果你有很多上面提到的方法可能是不切實際的。
要了解更多關於使用Enumeration
看到"Scala Enumerations"博客文章的缺點。 當心文章的結尾這種解決辦法是不銀子彈,並與模式匹配全面性檢查作爲Enumeration
確實問題。
享受