Il vantaggio principale dell'Enumerazione di Scala è la regolarità della sintassi.
Se si desidera aggiungere un comportamento agli elementi dell'enumerazione, è sufficiente estendere la classe Val
.
A Odersky piacciono per il loro caso d'uso più semplice come costanti int-valutate con nome. E ha appena promesso sulla mailing list, per la prima volta, che un supporto migliorato è all'orizzonte.
Ma I recentlyused per sostituire un elenco di stringhe, poiché l'insieme di valori è un po 'impostato, più bello di un set di stringhe per la ricerca.
Invece di
val stuff = List("foo", "bar", "baz")
object stuff extends Enumeration { val foo, bar, baz = Value }
o
scala> object stuff extends Enumeration { val foo, bar, baz = Value }
defined object stuff
scala> val junk = new Enumeration { val foo, bar, baz = Value }
junk: Enumeration{val foo: this.Value; val bar: this.Value; val baz: this.Value} = 1
scala> stuff.values contains junk.foo
<console>:10: error: type mismatch;
found : junk.Value
required: stuff.Value
stuff.values contains junk.foo
^
Comportamento:
scala> trait Alias { def alias: String }
defined trait Alias
scala> object aliased extends Enumeration {
| class Aliased extends Val with Alias {
| def alias = toString.permutations.drop(1).next }
| val foo, bar, baz = new Aliased }
defined object aliased
scala> abstract class X { type D <: Enumeration
| def f(x: D#Value) = x match { case a: Alias => a.alias
| case _ => x.toString } }
defined class X
scala> class Y extends X { type D = aliased.type }
defined class Y
scala> new Y().f(aliased.bar)
res1: String = bra
scala> new Y().f(stuff.foo)
<console>:13: error: type mismatch;
found : stuff.Value
required: aliased.Value
new Y().f(stuff.foo)
^
scala> new X { type D = junk.type }.f(junk.foo)
warning: there was one feature warning; re-run with -feature for details
res4: String = foo
ValueSet
è un insieme di bit:
scala> stuff.values contains aliased.bar
<console>:11: error: type mismatch;
found : aliased.Aliased
required: stuff.Value
stuff.values contains aliased.bar
^
scala> stuff.foo + aliased.bar
<console>:11: error: type mismatch;
found : aliased.Aliased
required: stuff.Value
stuff.foo + aliased.bar
^
scala> stuff.foo + stuff.bar
res8: stuff.ValueSet = stuff.ValueSet(foo, bar)
Altre cose che sembra funzionare a Scala di oggi:
scala> def f[E <: Enumeration](e: E)(v: e.Value) = e.ValueSet.empty + v
f: [E <: Enumeration](e: E)(v: e.Value)e.ValueSet
scala> f(stuff)(stuff.foo)
res14: stuff.ValueSet = stuff.ValueSet(foo)
scala> def g[E <: Enumeration](e: E)(a: Any) = a match { case _: e.Value => true case _ => false }
g: [E <: Enumeration](e: E)(a: Any)Boolean
scala> g(stuff)(stuff.foo)
res15: Boolean = true
scala> g(stuff)(junk.foo) // checking outer pointers
warning: there was one feature warning; re-run with -feature for details
res16: Boolean = false
scala> g(stuff)(aliased.foo)
res17: Boolean = false
Sembra Scala è not entirely friendly to Java enums: Enumeration
scala> Thread.State.NEW.ordinal
[snip]
scala.reflect.internal.FatalError:
Unknown type: <notype>(NEW), <notype> [class scala.reflect.internal.Types$UniqueConstantType, class scala.reflect.internal.Types$NoType$] TypeRef? false
while compiling: <console>
during phase: icode
library version: version 2.11.2
compiler version: version 2.11.2
reconstructed args:
last tree to typer: Apply(method ordinal)
tree position: line 8 of <console>
tree tpe: Int
symbol: final method ordinal in class Enum
symbol definition: final def ordinal(): Int (a MethodSymbol)
symbol package: java.lang
symbol owners: method ordinal -> class Enum
call site: constructor $read$$iw$$iw in package $line4
di Scala non è che dietro. http://stackoverflow.com/questions/21537148/scala-java-enumerations Non è conveniente quanto le classi/oggetti case di Scala. – Naetmul