Каковы примеры использования символьных литералов в Scala?

93

Использование символьных литералов не сразу понятно из того, что я прочитал о Scala. Кто-нибудь захочет поделиться с вами некоторыми реальными применениями?

Есть ли конкретная идиома Java, охватываемая символьными литералами? В каких языках есть похожие конструкции? Я исхожу из опыта работы с Python и не уверен, что на этом языке есть что-нибудь аналогичное.

Что побудило бы меня использовать «HelloWorld против HelloWorld»?

Благодарность

Джо Холлоуэй
источник

Ответы:

77

В терминах Java символы - это интернированные строки. Это означает, например, что сравнение эталонного равенства ( eqв Scala и ==в Java) дает тот же результат, что и обычное сравнение равенства ( ==в Scala и equalsв Java): 'abcd eq 'abcdвернет истину, а "abcd" eq "abcd"может и нет, в зависимости от прихоти JVM (ну, должно для литералов, но не для динамически создаваемых строк вообще).

Другие языки, которые используют символы, - это Lisp (который использует 'abcdкак Scala), Ruby ( :abcd), Erlang и Prolog ( abcd; они называются атомами вместо символов).

Я бы использовал символ, когда меня не волнует структура строки и я использую его исключительно как имя для чего-то. Например, если у меня есть таблица базы данных, представляющая компакт-диски, которая включает столбец с именем «цена», меня не волнует, что второй символ в «цене» - это «r», или о соединении имен столбцов; поэтому библиотека баз данных в Scala могла разумно использовать символы для имен таблиц и столбцов.

Алексей Романов
источник
25
Вероятно, стоит помнить, что == в Scala выполняет функцию .equals, поэтому на самом деле разница будет при использовании метода «eq», который ссылается на равенство. Однако есть один бонус: сравнение символов обходится очень дешево.
Calum
@Calum, как и сравнение двух строк. Стажеры Java (более-менее) все строки.
Элазар Лейбович
4
@Elazar: Это правда? У меня сложилось впечатление, что Java только интернировала литералы (т.е. почти все строки в тривиальных примерах и почти не строк в производственном ПО). Сказав, что варианты использования символов обычно представляют собой буквальные значения (я сомневаюсь, что вы часто строите их с нуля), возможно, главное преимущество, которое вы получаете, - это просто более описательный тип.
Calum
1
@Elazar Это не так, потому что символы могут полагаться на то, что их значение интернировано, тогда как со строками это необязательно и может оптимизировать некоторые варианты использования. Символы больше похожи на динамически создаваемые перечисления, чем на что-либо еще. Я подробно остановился на ответе, который я привел в своем последнем ответе; пожалуйста, прочтите это, чтобы узнать больше.
Calum
3
Итак, «привет, мир!» представляет собой последовательный набор символов, в то время как helloWorld является дружественным для людей значением, а не 14392.
CW Holeman II
26

Если у вас есть простые строки, представляющие, скажем, имена методов в коде, которые, возможно, передаются, вы не совсем правильно передаете вещи. Это своего рода проблема границы данных / кода, не всегда легко провести черту, но если бы мы сказали, что в этом примере эти имена методов представляют собой больше кода, чем данных, тогда мы хотим, чтобы что-то четко идентифицировало это .

В игру вступает символьный литерал, который четко различает любые старые строковые данные с конструкцией, используемой в коде. Это действительно именно то место, где вы хотите указать, это не просто некоторые строковые данные, а фактически часть кода. Идея, заключающаяся в том, что такие вещи, как ваша IDE, подчеркнет это по-другому, и, учитывая инструменты, вы можете реорганизовать их, а не выполнять поиск / замену текста.

Эта ссылка обсуждает это довольно хорошо.

Саэм
источник
2
Это полезное объяснение. Это заставляет меня думать об альтернативах перечислениям - что может быть неуклюжим
StephenBoesch
2

Python поддерживает внутреннюю глобальную таблицу «интернированных строк» с именами всех переменных, функций, модулей и т. Д. С помощью этой таблицы интерпретатор может ускорить поиск и оптимизацию. Вы можете форсировать этот процесс с помощью internфункции (sys.intern запустить в python3).

Кроме того, Java и Scala автоматически используют «интернированные строки» для более быстрого поиска. С помощью scala вы можете использовать этот internметод для принудительного вставки строки в строку, но этот процесс работает не со всеми строками. Символы выигрывают от гарантированного интернирования, поэтому проверки равенства одной ссылки достаточно для доказательства равенства или неравенства.

ChemaCortes
источник
1

Заметка: Symbols будет объявлено устаревшим, а затем будет удалено в Scala 3 (точка).

Ссылка: http://dotty.epfl.ch/docs/reference/dropped-features/symlits.html

Из-за этого я лично рекомендую Symbolsбольше не использовать (по крайней мере, в новом коде Scala). Как говорится в точечной документации:

Символьные литералы больше не поддерживаются

вместо этого рекомендуется использовать простой строковый литерал [...]

Juanmirocks
источник
1
Дикий, что я разместил этот вопрос 11 лет назад. Спасибо за продолжение
Джо Холлоуэй