Was sind einige Anwendungsbeispiele für Symbolliterale in Scala?

93

Die Verwendung von Symbolliteralen ist aus dem, was ich über Scala gelesen habe, nicht sofort ersichtlich. Würde es jemandem etwas ausmachen, einige reale Verwendungszwecke zu teilen?

Gibt es eine bestimmte Java-Sprache, die von Symbolliteralen abgedeckt wird? Welche Sprachen haben ähnliche Konstrukte? Ich komme aus Python und bin mir nicht sicher, ob diese Sprache etwas Analoges enthält.

Was würde mich motivieren, 'HelloWorld vs "HelloWorld" zu verwenden?

Vielen Dank

Joe Holloway
quelle

Antworten:

76

In Java sind Symbole internierte Zeichenfolgen. Dies bedeutet zum Beispiel, dass der Referenzgleichheitsvergleich ( eqin Scala und ==in Java) das gleiche Ergebnis liefert wie der normale Gleichheitsvergleich ( ==in Scala und equalsin Java): 'abcd eq 'abcdGibt true zurück, während "abcd" eq "abcd"dies je nach den Launen von JVM möglicherweise nicht der Fall ist (nun, sollte es sein) für Literale, aber nicht für Zeichenfolgen, die im Allgemeinen dynamisch erstellt werden).

Andere Sprachen, die Symbole verwenden, sind Lisp ( 'abcdwie Scala), Ruby ( :abcd), Erlang und Prolog ( abcdsie werden Atome anstelle von Symbolen genannt).

Ich würde ein Symbol verwenden, wenn mir die Struktur eines Strings egal ist, und es nur als Namen für etwas verwenden. Wenn ich beispielsweise eine Datenbanktabelle habe, die CDs darstellt und eine Spalte mit dem Namen "Preis" enthält, ist es mir egal, dass das zweite Zeichen in "Preis" "r" ist oder Spaltennamen verkettet werden. Eine Datenbankbibliothek in Scala könnte also vernünftigerweise Symbole für Tabellen- und Spaltennamen verwenden.

Alexey Romanov
quelle
25
Es ist wahrscheinlich erwähnenswert, dass == in Scala die .equals-Sache ausführt, also wäre der Unterschied wirklich, wenn die "eq" -Methode verwendet wird, die auf Gleichheit verweist. Ein Bonus ist jedoch, dass der Vergleich zwischen Symbolen extrem billig ist.
Calum
@Calum, ebenso wie der Vergleich zwischen zwei Strings. Java-Praktikanten (mehr oder weniger) alle Zeichenfolgen.
Elazar Leibovich
4
@ Elzar: Ist das wirklich wahr? Ich hatte den Eindruck, dass Java nur Literale internierte (dh fast alle Zeichenfolgen in trivialen Beispielen und fast keine Zeichenfolgen in Produktionssoftware). Allerdings sind die Anwendungsfälle von Symbolen normalerweise wörtliche Werte (ich bezweifle, dass Sie sie häufig von Grund auf neu erstellen). Der Hauptvorteil, den Sie erhalten, ist also wohl nur ein beschreibender Typ.
Calum
1
@Elazar Dies ist nicht der Fall, da sich Symbole darauf verlassen können, dass ihr Wert interniert wird, während dies bei Strings optional ist und einige Anwendungsfälle optimieren kann. Symbole sind mehr wie dynamisch erstellte Aufzählungen als alles andere. Darauf habe ich die Antwort näher eingegangen, die ich in meiner letzten Antwort verlinkt habe. Bitte lesen Sie es für mehr.
Calum
3
Also "Hallo Welt!" ist eine sequentielle Sammlung von Charakteren, während 'helloWorld eher ein menschenfreundlicher Wert als 14392 ist.
CW Holeman II
26

Wenn Sie einfache Zeichenfolgen haben, die beispielsweise Methodennamen im Code darstellen und möglicherweise weitergegeben werden, vermitteln Sie die Dinge nicht ganz angemessen. Dies ist eine Art Daten- / Code-Grenzproblem. Es ist nicht immer einfach, die Grenze zu ziehen. Wenn wir jedoch sagen würden, dass diese Methodennamen in diesem Beispiel mehr Code als Daten sind, möchten wir, dass etwas dies eindeutig identifiziert .

Es kommt ein Symbolliteral ins Spiel, bei dem nur alte Zeichenfolgendaten klar von einem im Code verwendeten Konstrukt unterschieden werden. Es ist nur wirklich dort, wo Sie angeben möchten, dies sind nicht nur einige Zeichenfolgendaten, sondern in gewisser Weise Teil des Codes. Die Idee, Dinge wie Ihre IDE zu sein, würde es anders hervorheben, und angesichts der Werkzeuge könnten Sie diese umgestalten, anstatt Textsuche / -ersetzung durchzuführen.

Dieser Link diskutiert es ziemlich gut.

Saem
quelle
1
Dies ist eine hilfreiche Erklärung. Es bringt mich dazu, über Alternativen zu Aufzählungen nachzudenken - was ungeschickt sein kann
javadba
2

Python verwaltet eine interne globale Tabelle mit "internierten Zeichenfolgen" mit den Namen aller Variablen, Funktionen, Module usw. Mit dieser Tabelle kann der Interpreter schnellere Suchen und Optimierungen durchführen. Sie können diesen Vorgang mit der internFunktion erzwingen ( sys.internin Python3).

Außerdem verwenden Java und Scala automatisch "internierte Zeichenfolgen" für schnellere Suchvorgänge. Mit scala können Sie die internMethode verwenden, um den Internierten eines Strings zu erzwingen, aber dieser Prozess funktioniert nicht mit allen Strings. Symbole profitieren davon, dass sie garantiert interniert werden. Daher reicht eine einzige Überprüfung der Referenzgleichheit aus, um Gleichheit oder Ungleichheit nachzuweisen.

ChemaCortes
quelle