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