Возможный дубликат:
Каковы некоторые примеры использования символьных литералов в Scala?Какова цель Symbol и почему он заслуживает особого синтаксиса литерала , например
'FooSymbol
?
Символы используются там, где у вас есть закрытый набор идентификаторов, которые вы хотите быстро сравнить. Когда у вас есть два экземпляра String
, их интернирование не гарантируется [1], поэтому для их сравнения вы должны часто проверять их содержимое, сравнивая длины и даже посимвольно проверяя, одинаковы ли они. С экземплярами Symbol
сравнения - это простая проверка eq
(например, ==
в Java), поэтому они являются постоянным временем (например, O (1)) для просмотра вверх.
Такая структура чаще используется в динамических языках (в частности, в коде Ruby и Lisp часто используются символы), поскольку в языках со статической типизацией обычно требуется ограничить набор элементов по типу.
При этом, если у вас есть хранилище ключей / значений, где есть ограниченный набор ключей, где будет неудобно использовать статический типизированный объект, Map [Symbol, Data]
-стиловая структура вполне может быть вам полезна.
Замечание об интернировании String
на Java (и, следовательно, на Scala) : Java String
в любом случае интернированы; в частности, строковые литералы автоматически интернируются, и вы можете вызвать метод intern ()
в экземпляре String
, чтобы вернуть интернированную копию. Однако не все String
интернированы, что означает, что среда выполнения должна выполнить полную проверку, если только они не являются одним и тем же экземпляром; интернирование ускоряет сравнение двух равных интернированных строк, но не улучшает время выполнения сравнения разных строк. Symbol
выигрывает от того, что гарантировано будет интернировано, поэтому в этом случае для доказательства равенства или неравенства будет достаточно одной проверки на равенство.
[1] Интернирование - это процесс, при котором при создании объекта вы проверяете, существует ли уже такой же объект, и используете его, если он существует. Это означает, что если у вас есть два равных объекта, они являются одним и тем же объектом (т.е. они равны по ссылкам). Недостатком этого является то, что поиск необходимого объекта может быть дорогостоящим, а разрешение на сборку мусора может потребовать сложной реализации.
Это не очень полезно в Scala и поэтому не используется широко. Как правило, вы можете использовать символ там, где хотите обозначить идентификатор.
Например, функция вызова отражения, которая была запланирована для версии 2.8.0, использовала синтаксис obj o 'method(arg1, arg2)
, где 'o' был методом, добавленным к Any, а Symbol был добавлен к метод apply(Any*) (оба с «прокачать мою библиотеку»).
Другой пример: если вы хотите создать более простой способ создания HTML-документов, то вместо использования «div» для обозначения элемента вы должны написать «div.Затем можно представить добавление операторов к Symbol для создания синтаксического сахара для создания элементов
.Символы
интернированы.
Цель состоит в том, чтобы Symbol
были более эффективными, чем String
и Symbol
с одинаковыми именами, ссылаются на один и тот же Symbol
. ] объект (чтобы иметь тот же хэш-код).
Взгляните на эту статью о символах Ruby: http://glu.ttono.us/articles/2005/08/19/understanding-ruby-symbols
Вы можете получить только имя Символ
:
scala> val aSymbol = 'thisIsASymbol
aSymbol: Symbol = 'thisIsASymbol
scala> assert("thisIsASymbol" == aSymbol.name)