Кажется, что на фронте памяти может быть разница, но в остальном они кажутся довольно похожими. Какие различия я должен знать?
Символы в ruby и константы в PHP на самом деле не эквивалентны.
Большинство реализаций ruby хранят нечто, называемое таблицей символов, которое является внутренним для интерпретатора. В таблице символов хранятся идентификаторы, используемые в программе, такие как имена методов, имена классов и т. Д. В указанной таблице. Поиск указанных имен выполняется на основе целочисленной позиции указанных имен в таблице символов.
Сами символы являются объектами, и между именами символов и объектами символов существует взаимно-однозначное соответствие. Так, когда у вас есть, например, def hello ...
и позвонить hello
метод где-то в программе, это относится к точно такому же объекту, как если бы вы ссылались :hello
, Таблица символов — это, по сути, способ избежать множества сравнений строк при обращении к часто используемым именам в программе.
Для иллюстрации рассмотрим следующий код:
class A
def hello
puts "the method name is #{__method__}"puts "the class of the method name is #{__method__.class}"puts "the object ID of the name hello is #{__method__.__id__}"end
end
A.new.hello
puts "the object id of :hello is #{:hello.__id__}"
Это выводит:
$ the method name is hello
the class of the method name is Symbol
the object ID of the name hello is 898268
the object id of :hello is 898268
Итак, имя метода ‘hello’ и символ: hello ссылаются на один и тот же объект. Хранение символов таким образом уменьшает выделение объектов — как вы намекали — и, соответственно, значительно ускоряет поиск часто используемых имен в программе.
Кроме того, вы не можете назначать значения для символов. например., :hello = "blah"
не сработает Потому что: hello имеет очень конкретное значение в соответствии с внутренней таблицей символов. Это еще одно очевидное различие между символами ruby и константами PHP.
В PHP константа — это идентификатор, связанный со значением, значение которого является неизменным в течение всего времени выполнения программы. Значением может быть любой объект или значение. Если у вас есть две константы PHP, которые ссылаются на одно и то же значение, например define("A", "value")
а также define("B", "value")
тогда это фактически два отдельных идентификатора, указывающих на два уникальных значения.
Так что пока A
а также B
там указывают на одно и то же семантическое содержание, они не указывают на один идентифицируемый объект. И они не сводятся к одному идентифицируемому объекту, ссылаясь на них. В PHP нет внутреннего хранилища, которое хранит карту общих символов для идентификаторов, как для символов в ruby. Поэтому я бы не сказал, что символы ruby вообще эквивалентны константам PHP.
Они не имеют ничего общего друг с другом. Спрашивать об их различиях — все равно, что спрашивать о различиях между Toyota Corolla и синим цветом.
постоянная является (в первом приближении) переменной, которая может быть назначена только один раз, во время инициализации. Константа неизменна ссылка на значение.
Символ — это значение, которое представляет идею «имени» (в смысле языка программирования), «идентификатора» (опять же, в смысле языка программирования) или «метки». Также как строка является значением, которое представляет идею «текста». Символы являются неизменными, непосредственными, и они оценивают себя.
Итак, символы — это значения, а константы — нет. (Константы являются ссылками в ценности). Символы оценивают сами по себе, константы оценивают на любое значение, на которое они ссылаются. Тип данных символов, по сути, предоставляет программисту кое-что, что есть у большинства языковых реализаций (включая Peachpie, P8, Quercus и другие реализации PHP), но обычно это не раскрывается: таблица символов. Символы не являются уникальными для Ruby, они также существуют в Smalltalk (откуда Ruby получил их), Newspeak, Self, большинстве Lisps (включая Clojure, Scheme, CommonLisp), Elixir, Erlang, ECMAScript, Scala и многих других.