Warum brauchen wir Aufzählungen in dynamisch getippten Sprachen?

32

Ich habe hier Code gelesen und festgestellt, dass in einer Enumeration die Namen von HTML-Tags gespeichert werden. Warum müssen wir das jemals tun? Welchen Nutzen bringt mir diese Strategie?

Ich weiß, wie nützlich Enums in kompilierten oder statisch typisierten Sprachen sind, aber wenn ich Enums in dynamisch typisierten Sprachen sehe, werde ich neugierig, wie der Beispielcode, den ich oben gezeigt habe. Die Frage dreht sich also im Grunde darum, warum wir Aufzählungen in dynamisch getippter Sprache brauchen oder brauchen wir sie überhaupt?

CodeYogi
quelle
38
Diese Frage lautet im Grunde "Warum brauchen wir Typen" .
user11153
1
Haben Sie das Repo durchsucht, um zu sehen, wie es heißt? Das würde Ihnen wahrscheinlich ein besseres Verständnis für die erhaltenen Antworten verschaffen.
RubberDuck
Wenn Sie haben: enum People { YOU, NPC, FOO, BAR }und eine Funktion, die ein (People) möchte int, können Sie alles einstecken, anstatt eine Zahl zu verwenden.
Evan Carslake
3
Fragen Sie nach dem Zweck dieser bestimmten "Aufzählung" oder nach dem Zweck von Aufzählungen im Allgemeinen in einer beliebigen Sprache? Ich würde davon ausgehen, dass die ersteren, aber alle aktuellen Antworten scheinen die letzteren zu denken ...
Meriton - im Streik

Antworten:

56

Ein Vorteil ist, dass der Compiler Sie informieren kann, wenn Sie versehentlich "ADRESS" oder "FEILDSET" eingeben, und Sie können es sofort beheben, anstatt sich zur Laufzeit unsinnig zu verhalten.

Während der Vorteil in statisch typisierten Sprachen weitaus nützlicher ist als in dynamischen, ist er dennoch nützlich, selbst wenn es sich um einen Laufzeitfehler handelt, da Sie eine Meldung erhalten, die auf ein Problem mit Ihrer case-Anweisung hinweist und nicht auf Ihre Daten.

Whatsisname
quelle
4
@amon: Sie könnten, aber Enums bietet Ihnen einen praktischen Mechanismus, um sicherzustellen, dass Sie keine Kollisionen haben.
Whatsisname
75
Ein Ort, an dem ich einmal im Monat gearbeitet habe, um einem Fehler nachzujagen, der durch die gute Idee einer anderen Person verursacht wurde, String-Konstanten anstelle von Aufzählungen, schlechten Editor-Schriftarten und einem versehentlich benannten Feld zu verwenden"PROF1LE_"
Gort the Robot
8
@amon Go macht genau das. Eine nette Sache bei Enums ist jedoch, dass der Compiler überprüfen kann, ob in Ihrer switch-Anweisung für jeden möglichen Enum-Wert eine Groß- / Kleinschreibung vorkommt.
weberc2
15
Dieser Code wurde in den 80er Jahren geschrieben. Sie werden das vielleicht nicht bemerken, aber dies war in einer Ära, in der einige Entwickler gelernt haben, sich mit physischen Schreibmaschinen zu entwickeln, die möglicherweise keinen einzigen Schlüssel hatten . Eigentlich ist mir klar, dass die fragliche Saite "Profi1e" war ... es sind 25 Jahre vergangen, daher ist mein Gedächtnis offensichtlich nicht perfekt.
Gort the Robot
4
@ DarrelHoffman: Ich bin überrascht, dass Sie überrascht sind. In Perl tippe ich häufig, $1wenn ich meine $i. (Zugegeben, ich tippe nie f1lestattdessen file- der $1Fehler wird durch die Tatsache ausgelöst, die $1in Perl sehr häufig vorkommt -, aber dennoch sind Fehler aller Art häufig. Vielleicht hatte der Entwickler ein Passwort prof1ledarin, wodurch er sie auf einen Tippfehler vorbereitet profilein nicht-Passwort-Kontexten.)
Ruakh
22

Aufzählungen sind nützlich für Situationen, in denen Sie eine feste Menge von Werten / Entitäten haben, die sinnvoll sind. Sie sind selbstdokumentierend und ermöglichen es dem Compiler, Dinge zu validieren, die sonst zur Laufzeit verbleiben würden. Sie sollten niemals verwendet werden, wenn die Menge der aussagekräftigen Werte nicht bekannt oder nicht streng begrenzt ist.

Ein nützlicheres Beispiel wäre so etwas wie HTTP-Antwortcodes. Anstatt eine Methode zu haben, die eine Zahl annimmt und den Namen und / oder die Beschreibung des Fehlers liefert, können Sie eine Reihe von Aufzählungen mit aussagekräftigen Namen, einem Code und einer Beschreibung usw. in einem sauberen Paket haben, die für die Werte maßgeblich sind erlaubt und müssen behandelt werden.

JimmyJames
quelle
1
"Selbstdokumentation" ist der wichtigste Teil. Ich würde eher prüfen, ob status === GEOLOCATION_ACQUIREDals status === 3, damit die Person, die diese Software wartet, versteht, was los ist. Wie Sie sagten, verhindert es auch ungültige Werte.
Nicolas Bouliane
11

Aufzählungen haben nichts mit OOP zu tun, und JavaScript hat keine Aufzählungen. Stattdessen werden Aufzählungen verwendet, wenn eine Auswahl zwischen einem festen Satz von Werten besteht. Ein Boolescher Wert ist beispielsweise eine Wahl zwischen true und false, die als implementiert werden kann enum Bool { False, True }. In einer GUI - Bibliothek, könnten wir eine ENUM für Ausrichtungen haben: enum HAlignment { LEFT = -1, CENTER = 0, RIGHT = 1 }.

Es ist normalerweise unerheblich, wie die Aufzählung implementiert wird. Wichtig ist, dass jeder mögliche Wert unterschiedlich ist. Viele Sprachen verwenden Ganzzahlen für Aufzählungen, obwohl einige wie Java beliebige Objekte unterstützen.

Bisher hätten wir genauso gut Konstanten verwenden können, z const int LEFT = -1, CENTER = 0, RIGHT = 1. Ein Compiler weiß jedoch, dass die Enum-Werte zusammengehören. Wenn ich also die Enum-Werte umschalte switch(value) {case LEFT: ...; case RIGHT: ...;}, kann der Compiler mich warnen, dass ich den CENTERFall vergessen habe. Dies kann eine erhebliche Zeitersparnis bedeuten. In Sprachen ohne Aufzählungen oder ohne Switch-Case-Konstrukt kann dies mit dem Besuchermuster simuliert werden, obwohl dies bei statischer Typisierung hilfreicher ist.

Der andere Vorteil ist, dass Aufzählungen als separater Typ behandelt werden können. Ich kann zum Beispiel deklarieren, dass eine Methode einen HAlignmentParameter und keine ganze Zahl akzeptiert. Der Code kann dann nicht kompiliert werden, wenn ich etwas anderes als einen der drei möglichen HAlignment-Werte bereitstelle. Die Aufzählungen von C sind jedoch nicht gut gekapselt, und die Aufzählungskonstanten können austauschbar mit ganzen Zahlen verwendet werden. Andere Sprachen sind hier strenger.

In JavaScript erhalten wir keinen dieser Vorteile. Das angegebene Beispiel deklariert ein Objekt, das als Aufzählung behandelt wird. Dies hat einige Vorteile für den Programmierer, zB erleichtert es die Dokumentation, gruppiert alle „Konstanten“ in einem einzigen Objekt,…. Es ist jedoch nur eine Konvention, dass ein solches Objekt enumartig ist.

Der Punkt hier ist, dass HTML nur eine begrenzte und bekannte Menge von Tags hat. Sie können sich die HTML5-Spezifikation ansehen und diese Elementnamen als Aufzählung in Ihren Code einfügen, wodurch es schwieriger wird, ein <blink>Tag in Ihr Programm einzuschleusen. Es ist besser, dieses Wissen an einem Ort zu kodieren, um Ihren Code mit speziellen String-Literalen (oder schlimmer noch mit magischen Zahlen) zu verunreinigen.

amon
quelle
In diesem Fall <blink>könnte mich nichts aufhalten , wenn ich eine Methode in Javascript übergebe, oder? aber in javahallo bricht los :)
CodeYogi
@CodeYogi ja, da JS kein statisches Typsystem hat und insbesondere kein Konzept für Aufzählungstypen. Ich kann jedoch einen Methodenparameter als "takes a TagName" dokumentieren, was einen Programmierer veranlassen würde, ihn aufzurufen, da foo(TagName.STRONG)dies etwas besser ist. Es wäre noch besser, wenn JS sich beschweren würde, wenn das Feld nicht existiert, aber hier bekommen wir nur eine, undefinedwenn ich es versuche TagName.BLINK. In JS ist es nicht viel wert, aber es ist ein Anfang.
amon
Hmm, der oben erwähnte Codelink verwendet Closure Compiler und ist daher dort sinnvoll.
CodeYogi
Da Clojure eine funktionale Sprache ist, bin ich mir nicht sicher, wie wichtig OOP für die Frage ist, aber abgesehen davon ist es wichtig, zwischen Enums zu unterscheiden, die im Allgemeinen nur eine Menge von Ganzzahlen (nicht OO) sind, und dem 'Typesafe Enum'-Muster, das OO ist und was Java unterstützt.
JimmyJames
@JimmyJames Ich spreche von JS, nicht über Clo j ure (die auf der Java - Plattform ausgeführt wird , auch OOP zu einem gewissen Grad unterstützt). Die Frage wurde mit oop markiert , weshalb ich sie am Anfang erwähne. Ich weiß nicht wirklich sehen , wie typsichere Aufzählungen zu OOP verbunden sind, das ist nur ein Typ Systemfunktion (viele Nicht-OOP - Sprachen haben Typ - Systeme :-))
amon
3

Auch wenn für Ihre Sprache keine Kompilierung erforderlich ist, werden Sie wahrscheinlich eine Art IDE oder Entwicklungstools verwenden, mit denen Sie eine Aufzählung besser unterstützen können als nur Zeichenfolgen.

Wenn Sie beispielsweise in Javascript eine Aufzählung wie ein Objektliteral verwenden, erhalten Sie von Ihrem Editor eine Code-Vervollständigung, und Ihr Code-Checker wie JSHint oder JSLint warnt Sie, wenn Sie versehentlich den falschen Wert verwenden.

Hansmaad
quelle
Ich denke, viele der anderen Antworten verfehlen oder schlagen sich um diesen Punkt herum. Die Verwendung eines 'Emums' in einer dynamischen Sprache kann für einen Compiler möglicherweise nichts bewirken, kann jedoch bestimmten IDEs, Dokumentationswerkzeugen und auch Menschen, die versuchen, den Code zu verstehen, wirklich helfen.
Robert
2

Der Sinn einer solchen Aufzählung könnte darin bestehen, Js Api (goog) eine Menge / ein Bündel zulässiger Tags zur Verfügung zu stellen. Welche? Diejenigen, die in W3C HTML 4.01 definiert sind ( siehe Dokumentation zu enum ). Es sind also Einstellungsgrenzen.

Das könnte das eigentliche Ziel sein oder auch nicht, aber es würde für diesen Zweck gut funktionieren.

Wenn Sie wissen, wie Javascript funktioniert, definiert der Code ein durch Strings indiziertes Array :-). Welcher Wert ein String ist, kann aber auch eine andere Komponente mit Attributen, Funktionen usw. sein. Lassen Sie Ihrer Fantasie freien Lauf und Sie werden überall Vorteile sehen.

Abgesehen von Javascript verwende ich häufig Aufzählungen zum Modellieren und Verwalten von Zustandsautomaten .

START> IN_PROGRESS> BESTÄTIGT> BEENDET> ...

In Java erlaubt switch Enums, also ist es ziemlich einfach, Zustände in einer Zustandsmaschine zu validieren , die gesamte Enumeration zu durchlaufen, Prioritäten zu definieren, indem komplexe Enums durchgeführt werden, ...

Ich benutze sie auch, um typisierte und nicht modifizierbare Konstanten zu definieren:

  • Ja Nein

Auch komplexe Aufzählungen (die sichere Transformationen / Parser ermöglichen)

  • Ja (1, wahr), Nein (0, falsch)

Aufgrund von Aufzählungen, die häufig zu meiner Modellschicht (Core) gehören, sind ihre Funktionen im gesamten System verfügbar, sodass sie zu einem Funktionsmodell werden und ich eine niedrige Kopplung behalte.

Was Aufzählungen (unter anderem) geben, sind Grenzen und Typisierung

Laiv
quelle