Что такое оператор двоеточия в Ruby?

Когда я говорю { :bla => 1, :bloop => 2 }, что именно делает :? Я где-то читал о том, как он похож на строку, но как-то символ.

Я не слишком понятен в концепции, может кто-нибудь просветить меня?

Ответ 1

:foo - это символ с именем "foo". Символы имеют отличительную особенность, что любые два символа, названные одинаковыми, будут идентичны:

"foo".equal? "foo"  # false
:foo.equal? :foo    # true

Это делает сравнение двух символов очень быстрым (поскольку используется только сравнение указателей, а не сравнение всех символов, подобных вам в строке), плюс вы не будете иметь миллион копий одного и того же символа, плавающего.

Кроме того, в отличие от строк символы неизменяемы.

Ответ 2

Просто, чтобы продемонстрировать некоторые вещи, упомянутые в ответах:

require 'benchmark'

n = 1_000_000

print '"foo".equal? "foo" -> ', ("foo".equal? "foo"), "\n"
print '"foo" == "foo"     -> ', ("foo" == "foo"    ), "\n"
print ':foo.equal? :foo   -> ', (:foo.equal? :foo  ), "\n"
print ':foo == :foo       -> ', (:foo == :foo      ), "\n"

Benchmark.bm(10) do |b|
  b.report('string')     { n.times { "foo".equal? "foo" }}
  b.report('str == str') { n.times { "foo" == "foo"     }}
  b.report('symbol')     { n.times { :foo.equal? :foo   }}
  b.report('sym == sym') { n.times { :foo == :foo       }}
end

Запуск его выходов:

"foo".equal? "foo" -> false
"foo" == "foo"     -> true
:foo.equal? :foo   -> true
:foo == :foo       -> true

Итак, сравнение строки с строкой с помощью equal? завершается с ошибкой, потому что это разные объекты, даже если они равны. == сравнивает содержимое, а эквивалентные проверки с символами намного быстрее.

                 user     system      total        real
string       0.370000   0.000000   0.370000 (  0.371700)
str == str   0.330000   0.000000   0.330000 (  0.326368)
symbol       0.170000   0.000000   0.170000 (  0.174641)
sym == sym   0.180000   0.000000   0.180000 (  0.179374)

Оба теста символов в основном такие же, как и скорость. После 1 000 000 итераций там всего 0,004733 секунды, поэтому я бы сказал, что это стирка, из которой можно использовать.

Ответ 3

Символы - это способ представления строк и имен в ruby.

Основное различие между символами и строками состоит в том, что символы с тем же именем инициализируются и существуют в памяти только один раз во время сеанса ruby.

Они полезны, когда вам нужно использовать одно и то же слово для представления разных вещей

Ответ 4

Есть некоторые цитаты из знаменитой книги Agile Web Development with Rails, которая может быть полезна и для понимания символа:

Rails использует символы для идентификации вещей. В частности, он использует их в качестве ключей при указании параметров метода и поиске вещей в хэшах.

redirect_to :action => "edit", :id => params[:id]

Вы можете думать о символах как строковых литералах, которые магически превращаются в константы. В качестве альтернативы вы можете рассматривать двоеточие как "вещь, названную", так что id - это "вещь с именем id".

Ответ 5

В ruby ​​каждый объект имеет уникальный идентификатор объекта, если вы пишете puts "hello".object_id в своем irb и получите возврат в течение двух раз, вы получите 2 разных возвращаемых значения, но если вы напишете :hello.object_id 2 раза, вы будете только получить то же самое возвращающее значение. Это должно было объяснить разницу.

Ответ 6

Если вы используете :foo => bar, foo будет символом. Преимущество символов заключается в том, что они уникальны. Когда вы вызываете элемент в хеше, вы делаете hash[:foo].

Символы требуют меньше памяти, чем строк, что также делает их полезными, если вы хотите сделать вашу программу немного быстрее.

Ответ 7

Это символ. В основном вы говорите, что два элемента хэша имеют ключи bla и bloop, как если бы вы использовали строки "bla" и "bloop". Однако они занимают меньше памяти, чем строки, и их легче печатать.

Ответ 8

Если вы знакомы с Java, вам может быть известно, что строки в Java неизменяемы. Символы аналогичны в этом смысле в Ruby. Они неизменяемы, то есть любое количество событий определенного символа :symbol будет отображаться только на один адрес памяти. И, следовательно, рекомендуется использовать символы везде, где это возможно, поскольку оно оптимизирует использование памяти.