[英]Lazy evaluation of Scala Enumerations?
考慮以下代碼片段,按字母順序排列從1到9的所有數字:
object AlphabetizedDigit extends Enumeration {
type AlphabetizedDigit = Value
val one, two, three, four, five, six, seven, eight, nine = Value
}
println(for(i <- Range(0, AlphabetizedDigit.maxId)) yield (i, AlphabetizedDigit(i)))
由於零索引, println
的輸出將有點不直觀:
jason@debian:~/code/atomicscala$ scala EnumIDRange.scala
Vector((0,one), (1,two), (2,three), (3,four), (4,five), (5,six), (6,seven), (7,eight), (8,nine))
解決此問題的一種方法是按以下方式更改AlphabetizedDigit
成員的定義:
val one = Value(1)
val two, three, four, five, six, seven, eight, nine = Value
然后確保Range
從1
而不是0
開始。 這樣的輸出就是直觀的輸出:
jason@debian:~/code/atomicscala$ scala EnumIDRange.scala
Vector((1,one), (2,two), (3,three), (4,four), (5,five), (6,six), (7,seven), (8,eight), (9,nine))
但是,我真的不喜歡這樣的事實,如果只想切換枚舉的起始索引,就需要將聲明分成兩行。 因此,我嘗試了以下方法,它們可以正常編譯:
val one, two, three, four, five, six, seven, eight, nine = Value(1)
但是,在運行時,由於使用了重復的ID,所以拋出了AssertionError
。 這在我看來很有意義,但是我很好奇為什么在運行時而不是編譯時拋出此錯誤。
您可以使用Enumeration的第二個構造函數,例如:
object AlphabetizedDigit extends Enumeration(1) {
type AlphabetizedDigit = Value
val one, two, three, four, five, six, seven, eight, nine = Value
}
表格doc: new Enumeration(initial: Int)
。
如果查看Scala的Enumeration的源代碼 ,則會看到以下內容:
/** The cache listing all values of this enumeration. */
@transient private var vset: ValueSet = null
@transient @volatile private var vsetDefined = false
和:
/** The values of this enumeration as a set.
*/
def values: ValueSet = {
if (!vsetDefined) {
vset = (ValueSet.newBuilder ++= vmap.values).result()
vsetDefined = true
}
vset
}
因此,似乎直到需要才實際評估值集,因此該錯誤僅在運行時顯示。 這看起來似乎是實現Enumeration
一種糟糕方法,但是我通常更喜歡使用密封的特征以及案例類和對象,因此無論如何* shrug *都很少處理Enumeration
。
至於從0
索引的問題,為什么不添加zero
條目呢?
val zero, one, two, three, four, five, six, seven, eight, nine = Value
如果需要,您仍然可以從1開始計數:
scala> println(for(i <- Range(1, AlphabetizedDigit.maxId)) yield (i, AlphabetizedDigit(i)))
Vector((1,one), (2,two), (3,three), (4,four), (5,five), (6,six), (7,seven), (8,eight), (9,nine))
或僅從0開始計數並獲得所有十位數:
println(for(i <- Range(0, AlphabetizedDigit.maxId)) yield (i, AlphabetizedDigit(i)))
Vector((0,zero), (1,one), (2,two), (3,three), (4,four), (5,five), (6,six), (7,seven), (8,eight), (9,nine))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.