Der Hauptvorteil von Scala's Enumeration ist die Regelmäßigkeit der Syntax.
Wenn Sie den Elementen Ihres Enums ein Verhalten hinzufügen möchten, erweitern Sie einfach seine Val
Klasse.
Odersky mag sie für ihren einfachsten Anwendungsfall als benannte int-werte Konstanten. Und er hat gerade auf der Mailingliste zum ersten Mal versprochen, dass eine verbesserte Unterstützung am Horizont ist.
Aber ich recentlyused sie eine Liste von Zeichenfolgen zu ersetzen, da die Menge der Werte ein wenig gesetzt ist, schöner als eine Reihe von Zeichenfolgen für die Suche.
Statt
val stuff = List("foo", "bar", "baz")
object stuff extends Enumeration { val foo, bar, baz = Value }
oder
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
^
Verhalten:
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
ist ein Bit gesetzt:
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)
Andere Sachen, die in der heutigen Scala zu funktionieren scheint:
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
Es sieht aus wie Scala ist not entirely friendly to Java enums:
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
Scala Enumeration nicht, dass hinter ist. http://stackoverflow.com/questions/21537148/scala-java-enumerations Es ist nur nicht so bequem wie Scala Fall Klassen/Objekte. – Naetmul