Это видео рассказывает вам все, что вам нужно знать о символах.
Тотимедли
Ответы:
249
:fooэто символ с именем "foo". Символы имеют отличительную особенность в том, что любые два символа с одинаковыми именами будут идентичны:
"foo".equal?"foo"# false:foo.equal?:foo # true
Это делает сравнение двух символов действительно быстрым (поскольку проводится сравнение только по указателю, а не по сравнению со всеми символами, как в строке), плюс у вас не будет плавать миллионы копий одного и того же символа.
Кроме того, в отличие от строк, символы являются неизменными.
просто интересно, почему литеральная строка не поддерживает интернирование строк?
onmyway133
5
@ onmyway133 Потому что строки Руби изменчивы. Стажировка относится только к неизменным значениям.
Крис Джестер-Янг
3
а) Почему "foo".equal? "foo"ложно? б) Можете ли вы ссылаться на символ в любом месте, по существу делая их как глобальные переменные?
Arc676
2
@ Arc676 1. equal?в Ruby происходит сравнение тождеств. Каждый строковый литерал, например "foo", создает новый экземпляр строки. Это работает так, потому что строки в Ruby являются изменяемыми. 2. Символы являются глобальными, но больше похожи на глобальные константы, чем на глобальные переменные, поскольку символы не имеют состояния. Таким образом, использование символов не является антипаттерном в смысле глобальных переменных.
Крис Джестер-Янг
2
@ Arc676 "foo" == "foo"# => true
Филипп Бартузи
44
Просто чтобы продемонстрировать некоторые вещи, упомянутые в ответах:
Таким образом, сравнивать строку со строкой с помощью equal?сбоя, потому что это разные объекты, даже если они имеют одинаковое содержимое. ==сравнивает содержимое, и эквивалентные проверки с символами выполняются намного быстрее.
user system total real
string 0.3700000.0000000.370000(0.371700)
str == str 0.3300000.0000000.330000(0.326368)
symbol 0.1700000.0000000.170000(0.174641)
sym == sym 0.1800000.0000000.180000(0.179374)
Оба теста символов в основном такие же, как скорость. После 1 000 000 итераций разница составляет всего 0,004733 секунды, так что я бы сказал, что между ними стоит промывка.
Очень полезно! В моей системе ==результат получился быстрее, чем .equal?для сравнения строк и символов. Сравнение символов в 3 раза быстрее, чем сравнение строк.
Мельвинким
33
Символы - это способ представления строк и имен в ruby.
Основное различие между символами и строками состоит в том, что символы с одинаковым именем инициализируются и существуют в памяти только один раз во время сеанса ruby.
Они полезны, когда вам нужно использовать одно и то же слово, чтобы представлять разные вещи
Вот несколько цитат из известной книги Agile Web Development с Rails , которая может быть полезна и для понимания символа :
Rails использует символы для идентификации вещей. В частности, он использует их в качестве ключей при именовании параметров метода и поиске вещей в хешах.
redirect_to :action =>"edit",:id => params[:id]
Вы можете думать о символах как о строковых литералах, которые волшебным образом превращаются в константы. В качестве альтернативы, вы можете считать двоеточие означающим «вещь с именем», поэтому: id - это «вещь с именем id».
В ruby каждый объект имеет уникальный идентификатор объекта, если вы напишите puts "hello".object_idв своем irb и нажмете return два раза, вы получите 2 разных возвращаемых значения, но если вы напишите :hello.object_id2 раза, вы получите только одно возвращаемое значение. Это должно было объяснить разницу.
В основном оператор двоеточия предназначен для назначения символа
Сезар-младший Родригес,
2
Если вы используете :foo => bar, foo будет символом. Преимущество символов в том, что они уникальны. Когда вы вызываете элемент в хэше, вы делаете hash[:foo].
Символы требуют меньше памяти, чем строки, что также делает их полезными, если вы хотите сделать свою программу немного быстрее.
Это символ По сути, вы говорите, что у двух элементов хеша есть ключи blaи bloop, как если бы вы использовали строки "bla"и "bloop". Однако они занимают меньше памяти, чем строки, и их легче набирать.
Во всех этих ответах пропущена одна дополнительная заманчивая деталь ... если вы зафиксируете символ: foo, вы получите ... угадайте, что ... строка "foo". следовательно
Если вы знакомы с Java, вы можете знать, что строки в Java являются неизменяемыми. Символы похожи в этом смысле в Ruby. Они являются неизменными, т. Е. Любое количество вхождений конкретного символа :symbolбудет отображаться только на один адрес памяти. И, следовательно, рекомендуется использовать символы везде, где это возможно, поскольку это оптимизирует использование памяти.
Тот факт, что символы являются неизменяемыми, гарантирует, что они всегда будут одним и тем же экземпляром во всем приложении, и, следовательно, они гарантированно будут одним и тем же объектом. Проверьте эти ссылки: Troubleshooters.com/codecorn/ruby/symbols.htm robertsosinski.com/2009/01/11/… Вы найдете больше информации, если вы Google.
Дхрува Сагар
Я говорю о вашей аналогии с Java. Строки Java не являются аналогами символов. Строковые литералы Java - это не все строки.
smartnut007
Возможно, мое утверждение не было достаточно ясным. Они аналогичны друг другу только в том, что они неизменны.
Дхрува Сагар
@DhruvaSagar: аналогия была бы лучше , если бы вы использовали Objective C - х NSString. Там "foo"всегда будет равна "foo", потому что внутренне строки , которые являются такими же , как раз указывают на. Ответ все еще будет сбивать с толку, хотя.
Ответы:
:foo
это символ с именем "foo". Символы имеют отличительную особенность в том, что любые два символа с одинаковыми именами будут идентичны:Это делает сравнение двух символов действительно быстрым (поскольку проводится сравнение только по указателю, а не по сравнению со всеми символами, как в строке), плюс у вас не будет плавать миллионы копий одного и того же символа.
Кроме того, в отличие от строк, символы являются неизменными.
источник
"foo".equal? "foo"
ложно? б) Можете ли вы ссылаться на символ в любом месте, по существу делая их как глобальные переменные?equal?
в Ruby происходит сравнение тождеств. Каждый строковый литерал, например"foo"
, создает новый экземпляр строки. Это работает так, потому что строки в Ruby являются изменяемыми. 2. Символы являются глобальными, но больше похожи на глобальные константы, чем на глобальные переменные, поскольку символы не имеют состояния. Таким образом, использование символов не является антипаттерном в смысле глобальных переменных."foo" == "foo"
# => trueПросто чтобы продемонстрировать некоторые вещи, упомянутые в ответах:
Запуск его выводит:
Таким образом, сравнивать строку со строкой с помощью
equal?
сбоя, потому что это разные объекты, даже если они имеют одинаковое содержимое.==
сравнивает содержимое, и эквивалентные проверки с символами выполняются намного быстрее.Оба теста символов в основном такие же, как скорость. После 1 000 000 итераций разница составляет всего 0,004733 секунды, так что я бы сказал, что между ними стоит промывка.
источник
==
результат получился быстрее, чем.equal?
для сравнения строк и символов. Сравнение символов в 3 раза быстрее, чем сравнение строк.Символы - это способ представления строк и имен в ruby.
Основное различие между символами и строками состоит в том, что символы с одинаковым именем инициализируются и существуют в памяти только один раз во время сеанса ruby.
Они полезны, когда вам нужно использовать одно и то же слово, чтобы представлять разные вещи
источник
Вот несколько цитат из известной книги Agile Web Development с Rails , которая может быть полезна и для понимания символа :
источник
В ruby каждый объект имеет уникальный идентификатор объекта, если вы напишите
puts "hello".object_id
в своем irb и нажмете return два раза, вы получите 2 разных возвращаемых значения, но если вы напишите:hello.object_id
2 раза, вы получите только одно возвращаемое значение. Это должно было объяснить разницу.источник
Если вы используете
:foo => bar
, foo будет символом. Преимущество символов в том, что они уникальны. Когда вы вызываете элемент в хэше, вы делаетеhash[:foo]
.Символы требуют меньше памяти, чем строки, что также делает их полезными, если вы хотите сделать свою программу немного быстрее.
источник
Это символ По сути, вы говорите, что у двух элементов хеша есть ключи
bla
иbloop
, как если бы вы использовали строки"bla"
и"bloop"
. Однако они занимают меньше памяти, чем строки, и их легче набирать.источник
Во всех этих ответах пропущена одна дополнительная заманчивая деталь ... если вы зафиксируете символ: foo, вы получите ... угадайте, что ... строка "foo". следовательно
Следовательно ... для программистов Perl ... это ответ Руби на "голое слово".
источник
Если вы знакомы с Java, вы можете знать, что строки в Java являются неизменяемыми. Символы похожи в этом смысле в Ruby. Они являются неизменными, т. Е. Любое количество вхождений конкретного символа
:symbol
будет отображаться только на один адрес памяти. И, следовательно, рекомендуется использовать символы везде, где это возможно, поскольку это оптимизирует использование памяти.источник
NSString
. Там"foo"
всегда будет равна"foo"
, потому что внутренне строки , которые являются такими же , как раз указывают на. Ответ все еще будет сбивать с толку, хотя.