Jakie są przykładowe przypadki użycia literałów symboli w Scali?

93

Użycie literałów symboli nie jest od razu jasne z tego, co przeczytałem w Scali. Czy ktoś chciałby podzielić się niektórymi zastosowaniami w prawdziwym świecie?

Czy istnieje określony idiom Java objęty literałami symboli? Jakie języki mają podobne konstrukcje? Pochodzę z języka Python i nie jestem pewien, czy jest coś podobnego w tym języku.

Co zmotywowałoby mnie do użycia „HelloWorld vs„ HelloWorld ”?

Dzięki

Joe Holloway
źródło

Odpowiedzi:

77

W języku Java symbole są łańcuchami wewnętrznymi. Oznacza to na przykład, że porównanie równości odniesień ( eqw Scali i ==Javie) daje taki sam wynik jak normalne porównanie równości ( ==w Scali i equalsJavie): 'abcd eq 'abcdzwróci wartość true, ale "abcd" eq "abcd"może nie, w zależności od kaprysów JVM (cóż, powinno dla literałów, ale nie dla łańcuchów tworzonych dynamicznie).

Inne języki, które używają symboli to Lisp (który używa 'abcdjak Scala), Ruby ( :abcd), Erlang i Prolog ( abcd; nazywane są atomami zamiast symboli).

Użyłbym symbolu, gdy nie obchodzi mnie struktura łańcucha i używam go wyłącznie jako nazwy czegoś. Na przykład, jeśli mam tabelę bazy danych reprezentującą płyty CD, która zawiera kolumnę o nazwie „cena”, nie obchodzi mnie, że drugi znak w polu „cena” to „r”, czy też konkatenacja nazw kolumn; więc biblioteka bazy danych w Scali mogłaby rozsądnie używać symboli dla nazw tabel i kolumn.

Alexey Romanov
źródło
25
Prawdopodobnie warto pamiętać, że == w Scali robi to .equals, więc tak naprawdę różnica byłaby w przypadku użycia metody „eq”, która odwołuje się do równości. Zaletą jest jednak to, że porównanie symboli jest niezwykle tanie.
Calum
@Calum, as to porównanie dwóch ciągów. Stażyści Java (mniej więcej) wszystkie ciągi.
Elazar Leibovich
4
@Elazar: Czy to naprawdę prawda? Miałem wrażenie, że Java internuje tylko literały (tj. Prawie wszystkie łańcuchy w trywialnych przykładach i prawie żadnych łańcuchów w oprogramowaniu produkcyjnym). Powiedziawszy, że przypadki użycia symboli są zwykle wartościami dosłownymi (wątpię, byś często tworzył je od zera), więc prawdopodobnie główną zaletą, jaką otrzymujesz, jest po prostu typ bardziej opisowy.
Calum
1
@Elazar Nie są, ponieważ symbole mogą polegać na internalizacji ich wartości, podczas gdy w przypadku łańcuchów jest to opcjonalne i może zoptymalizować niektóre przypadki użycia. Symbole bardziej przypominają wyliczenia tworzone dynamicznie niż cokolwiek innego. Rozwinąłem to na podstawie odpowiedzi, którą połączyłem w mojej ostatniej odpowiedzi; przeczytaj to po więcej.
Calum,
3
A więc „witaj, świecie!” jest sekwencyjną kolekcją znaków, podczas gdy „helloWorld jest wartością przyjazną ludziom, a nie 14392.
CW Holeman II
26

Jeśli masz w kodzie zwykłe ciągi reprezentujące nazwy metod powiedz, które być może są przekazywane, nie do końca przekazujesz rzeczy w odpowiedni sposób. Jest to rodzaj problemu z granicami danych / kodu, nie zawsze łatwo jest narysować linię, ale gdybyśmy mieli powiedzieć, że w tym przykładzie te nazwy metod są bardziej kodem niż danymi, to chcemy, aby coś wyraźnie to zidentyfikowało .

W grę wchodzi literał symbolu, który wyraźnie rozróżnia wszystkie stare dane łańcuchowe z konstrukcją używaną w kodzie. Po prostu jest tam, gdzie chcesz wskazać, nie są to tylko niektóre dane tekstowe, ale w rzeczywistości w jakiś sposób część kodu. Pomysł polegający na tym, że rzeczy takie jak twoje IDE podkreśliłyby to inaczej, a biorąc pod uwagę narzędzia, możesz je refaktoryzować, zamiast wyszukiwać / zastępować tekst.

Ten link dość dobrze to omawia.

Saem
źródło
2
To jest pomocne wyjaśnienie. To sprawia, że ​​myślę w kategoriach alternatyw dla wyliczeń - które mogą być niezdarne
javadba
2

Python utrzymuje wewnętrzną, globalną tabelę „wewnętrznych łańcuchów” z nazwami wszystkich zmiennych, funkcji, modułów itp. Dzięki tej tabeli interpreter może szybciej wyszukiwać i optymalizować. Możesz wymusić ten proces internfunkcją ( sys.internw python3).

Ponadto Java i Scala automatycznie używają „wewnętrznych ciągów znaków” w celu przyspieszenia wyszukiwania. Dzięki scali możesz użyć internmetody do wymuszenia stażysty ciągu, ale ten proces nie działa ze wszystkimi ciągami. Symbole korzystają z gwarancji internowania, więc jedno sprawdzenie równości odniesienia wystarczy, aby udowodnić równość lub nierówność.

ChemaCortes
źródło
1

Uwaga: Symbolszostaną wycofane, a następnie usunięte w Scala 3 (dotty).

Źródła: http://dotty.epfl.ch/docs/reference/dropped-features/symlits.html

Z tego powodu osobiście odradzam używanie go Symbols(przynajmniej w nowym kodzie scala). Jak stwierdza dokumentacja dotty:

Literały symboli nie są już obsługiwane

zamiast tego zaleca się użycie zwykłego literału ciągu [...]

juanmirocks
źródło
1
Dziki, że opublikowałem to pytanie 11 lat temu. Dzięki za kontynuację
Joe Holloway