2009-04-23 16 views
79

Używanie literałów symboli nie jest natychmiast jasne z tego, co przeczytałem na Scali. Czy ktoś miałby ochotę podzielić się realnymi zastosowaniami?Jakie są przykładowe przypadki użycia literałów symboli w Scali?

Czy istnieje konkretny idiom Java, który jest objęty literałami symboli? Jakie języki mają podobne konstrukcje? Pochodzę z tła Python i nie wiem, czy jest coś podobnego w tym języku.

Co zmotywuje mnie do używania "HelloWorld vs" HelloWorld "?

Dzięki

Odpowiedz

62

W języku Java symbole są internowanymi ciągami. Oznacza to, na przykład, że porównanie równości odniesienia (eq w Scala i == w Javie) daje taki sam wynik jak normalnego stosunku równości (== w Scala i equals w Javie): 'abcd eq 'abcd zwróci true, natomiast "abcd" eq "abcd" może nie, w zależności od JVM na kaprysy (cóż, powinno to być dla literałów, ale nie dla ciągów generowanych dynamicznie w ogóle).

innych języków, w których symbole mają Lisp (który wykorzystuje 'abcd jak Scala), Ruby (:abcd) Erlang i startowych (abcd, są nazywane węgla zamiast symbole).

Użyłbym symbolu, gdybym nie dbał o strukturę struny i używał jej wyłącznie jako nazwy czegoś. Na przykład, jeśli mam tabelę bazy danych reprezentującą dyski CD, która zawiera kolumnę o nazwie "cena", nie obchodzi mnie, że druga postać w "cenie" to "r", lub o łączenie nazw kolumn; więc biblioteka baz danych w Scali może rozsądnie używać symboli dla nazw tabel i kolumn.

+22

Warto chyba pamiętać, że == w Scali robi to.równa się rzeczy, więc tak naprawdę różnica byłaby wtedy, gdy używamy metody "eq", która odwołuje się do równości. Jedną z premii jest jednak to, że porównanie symboli jest niezwykle tanie. – Calum

+0

@ Calum, podobnie jak porównanie dwóch ciągów. Praktykanci Java (więcej lub mniej) wszystkie ciągi. –

+4

@Elazar: Czy to prawda? Miałem wrażenie, że Java tylko internowała literały (tj. Prawie wszystkie ciągi w trywialnych przykładach i prawie żadnych ciągów w oprogramowaniu produkcyjnym). Mówiąc, że przypadki użycia symboli są zazwyczaj wartościami dosłownymi (wątpię, że często je budujesz od podstaw), więc prawdopodobnie główna korzyść, którą otrzymujesz, jest po prostu opisowym typem. – Calum

24

Jeśli masz zwykły ciągi reprezentujące powiedzieć nazwy metod w kodzie, który być może przejdzie dookoła, nie jesteś dość przenoszenia rzeczy odpowiednio. Jest to rodzaj problemu z granicami danych/kodów, nie zawsze jest to łatwe do narysowania linii, ale gdybyśmy powiedzieli, że w tym przykładzie te nazwy metod są bardziej kodowane niż dane, to chcemy coś wyraźnie zidentyfikować, .

Symbol Literal wchodzi w grę, w której wyraźnie odróżnia się tylko stare dane ciągu od konstruktu używanego w kodzie. To naprawdę tam, gdzie chcesz wskazać, to nie tylko niektóre dane ciągowe, ale w rzeczywistości w pewnym sensie część kodu. Pomysł polegający na tym, że twoje IDE podkreślałoby to inaczej, i biorąc pod uwagę oprzyrządowanie, mógłbyś je zastąpić, zamiast wyszukiwać tekst/zastępować tekst.

Ten link omawia go dość dobrze.

+1

To jest pomocne wyjaśnienie. To sprawia, że ​​myślę w kategoriach alternatywy do wyliczenia - które może być niezręczne. – javadba

1

Python przechowuje wewnętrzną globalną tabelę "internowanych ciągów" z nazwami wszystkich zmiennych, funkcji, modułów itp. Za pomocą tej tabeli interpreter może szybciej wyszukiwać i optymalizować. Możesz wymusić ten proces za pomocą funkcji intern (sys.intern w python3).

Ponadto, Java i Scala automatycznie używają "internowanych ciągów" dla szybszych wyszukiwań. W programie scala można użyć metody intern, aby wymusić stację ciągu znaków, ale ten proces nie działa ze wszystkimi ciągami. Symbole odnoszą korzyści z zagwarantowania, że ​​zostaną internowane, więc jeden sprawdzian równości referencyjnej jest wystarczający do udowodnienia równości lub nierówności.

Powiązane problemy