Re: Scala
- From: Patrick Roemer <sangamon@xxxxxxxxxxxxx>
- Date: Mon, 20 Jul 2009 21:08:59 +0200
Responding to Heiner Kücker:
Dort wurde als ein Unterschied von vielen zu Java aufgeführt,
dass es keine Enums mehr gibt, dafür aber
einen erweiterten Switch.
Nicht wirklich "dafuer". Es gibt Pattern-Matching ueber Case-Classes,
und das ist deutlich generischer und maechtiger als das, was man in Java
durch das Hinzufuegen von Enums zu den primitiven Typen als erlaubte
Kandidaten im switch bekommt.
Den Sinn habe ich nicht ganz verstanden, denn meiner
Meinung nach sind Enums ein Teil der statischen
Modellierung.
In Scala gibt es geschlossene Klassen und "ad hoc"-Objekte. Damit hat
man im Prinzip alles, was enums auch bieten, mit Ausnahme der Auflistung
aller Elemente eines enum - die muss man wohl tatsaechlich von Hand
verwalten, wenn man das braucht. Mal ein an den Haaren herbeigezogenes
Beispiel:
sealed trait AndOrEnum extends Function2[Boolean, Boolean, Boolean]
case object And extends AndOrEnum {
def apply(a: Boolean, b: Boolean) = a && b
}
case object Or extends AndOrEnum {
def apply(a: Boolean, b: Boolean) = a || b
}
AndOrEnum kann in anderen Sourcefiles nicht mehr erweitert werden, also
gibt es genau zwei Objekte von diesem Typ. Damit hat man ein typsicheres
enum und keinen dringenden Bedarf fuer speziellen Support auf
Sprachebene. Mit switch bzw. Pattern-Matching hat das zunaechst mal gar
nichts zu tun - man kann es nur einfach nutzen, wie fuer alle Case-Classes.
def execute(ao: AndOrEnum, a: Boolean, b: Boolean) {
println(a + " " + str(ao) + " " + b + " = " + ao(a,b))
}
def str(ao: AndOrEnum) =
ao match {
case And => "and"
case Or => "or"
}
execute(Or, true, false)
execute(And, true, false)
$ true or false = true
$ true and false = false
Alternativ gibt es in der Standard-API auch eine enum-Implementierung:
http://www.scala-lang.org/docu/files/api/scala/Enumeration.html
Da gibt's dann auch die Auflistung aller Elemente out-of-the-box.
In einem prozeduralen Konstrukt switch sehe ich
da keinen Vorteil.
Das ist an Pattern-Matching ueber algebraischen Datentypen wie in
Haskell angelehnt, und damit eher funktional. (Insbesondere handelt es
sich um einen Ausdruck mit einem Rueckgabewert, nicht um ein
Steuerungskonstrukt wie in Java.)
Die Prüfung, ob in einem Switch alle Werte eines
Enum abgedeckt wurden ist nach meiner Meinung
ein Feature der IDE, nicht der Sprache, so dass
die IDE hier Schwächen der Java ausgleicht.
Das tun die IDE-Features fuer Java unbestritten oftmals. Aber...
enum AndOr {
AND, OR;
}
int id(AndOr andOr) {
switch(andOr) {
case AND:
return 0;
case OR:
return 1;
}
}
Wo hilft mir denn hier die IDE? Ich muss einen Bogus-Default einbauen.
(Und ich bekomme dieselbe Fehlermeldung, wenn ich einen Fall vergessen
habe.) Scala merkt, wenn ich alle Werte abgedeckt habe, und wenn nicht,
bekomme ich vom Compiler ein "match is not exhaustive".
Noch ein bisschen mehr zum Thema enums in Scala:
http://www.nabble.com/-scala--Enum-in-Scala--td11421904.html
http://alblue.blogspot.com/2007/12/scala-introduction-to-scala-case.html
http://babyloncandle.blogspot.com/2008/01/what-is-algebraic-data-type.html
Viele Gruesse,
Patrick
.
- Follow-Ups:
- Re: Scala
- From: Heiner Kücker
- Re: Scala
- Prev by Date: Re: NAT Traversal mit SSL
- Next by Date: Problem mit der Java Control Panel
- Previous by thread: Re: Scala
- Next by thread: Re: Scala
- Index(es):
Relevant Pages
|
Loading