Является ли StringBuffer таким же, как Strings в Ruby, а Symbols - тем же, что и обычные строки Java? - PullRequest
3 голосов
/ 18 июля 2011

Я только начал читать эту книгу Eloquent Ruby , и я дошел до главы о символах в Ruby.

Строки в Ruby являются изменяемыми, что означает, что каждая строка выделяет память, так как содержимое может меняться, и даже если содержимое равно. Если мне нужна изменяемая строка в Java, я бы использовал StringBuffer. Однако, поскольку обычные строки Java являются неизменяемыми, один объект String может совместно использоваться несколькими ссылками. Поэтому, если бы у меня было две обычные строки с содержимым «Hello World», обе ссылки указывали бы на один и тот же объект.

Значит, назначение символов в Ruby на самом деле совпадает с "обычными" объектами String в Java? Это функция, предоставляемая программисту для оптимизации памяти?

Что-то из того, что я написал здесь, правда? Или я неправильно понял концепцию символов?

Ответы [ 2 ]

5 голосов
/ 18 июля 2011

Символы близки к строкам в Ruby, но они не эквивалентны обычным строкам Java, хотя они также имеют некоторые общие черты, такие как неизменяемость.Но есть небольшая разница - есть несколько способов получить ссылку на символ (подробнее об этом позже).

В Ruby вполне возможно конвертировать два назад и вперед.Существует строка # to_sym для преобразования строки в символ, а есть символ # to_s для преобразования символа в строку.Так в чем же разница?

Чтобы процитировать RDoc для Symbol:

Один и тот же объект Symbol будет создан для данного имени или строки на время выполнения программы, независимо от контекста или значенияэто имя.

Символы являются уникальными идентификаторами.Если интерпретатор Ruby споткнется, скажем, :mysymbol в первый раз, вот что происходит: внутренне символ сохраняется в таблице, если он еще не существует (во многом как «таблица символов», используемая синтаксическими анализаторами;происходит с использованием функции C rb_intern в CRuby / MRI), в противном случае Ruby будет искать существующее значение в таблице и использовать его.После того, как символ будет создан и сохранен в таблице, с тех пор, куда бы вы ни ссылались на Символ :mysymbol, вы получите тот же объект, который был сохранен в этой таблице.

Рассмотрим этот фрагмент кода:

sym1 = :mysymbol
sym2 = "mysymbol".to_sym

puts sym1.equal?(sym2) # => true, one and the same object

str1 = "Test"
str2 = "Test"

puts str1.equal?(str2) # => false, not the same object

, чтобы заметить разницу.Это иллюстрирует основное различие между строками Java и символами Ruby.Если вам нужно равенство объектов для строк в Java, вы добьетесь этого только в том случае, если вы сравните точно такую ​​же ссылку на эту строку, тогда как в Ruby можно получить ссылку на символ несколькими способами, как вы видели в примере выше.

Уникальность символов делает их идеальными ключами в хешах: производительность поиска улучшена по сравнению с обычными строками, поскольку вам не нужно явно хешировать свой ключ, как этого требует строка, вы можете просто использоватьуникальный идентификатор символа для поиска напрямую.Написав :somesymbol, вы говорите Руби «дать мне одну вещь, которую вы сохранили под идентификатором« somesymbol »».Таким образом, символы являются вашим первым выбором, когда вам нужно однозначно идентифицировать вещи, как в:

  • хеш-ключах
  • именовании или обращении к именам переменных, методов и констант (например, obj.send: method_name)

Но, как указывает Джим Вейрих в приведенной ниже статье, символы не являются строками, даже в смысле утки.Вы не можете объединить их, получить их размер или получить от них подстроки (если только вы сначала не конвертируете их в строки).Поэтому вопрос о том, когда использовать строки, прост: как говорит Джим:

Используйте строки всякий раз, когда вам нужно… мм… строковое поведение.

Некоторые статьи отема:

1 голос
/ 18 июля 2011

Разница в том, что строки Java не обязательно должны указывать на один и тот же объект, если они содержат одинаковый текст. При объявлении константных строк в вашем коде это обычно так, поскольку компилятор поместит их в пул констант.

Однако, если вы динамически создаете строку во время выполнения в Java, две строки могут точно указывать на разные объекты и при этом содержать один и тот же текст. Однако вы можете форсировать это, усваивая объекты String (вызывая String.intern (), см. Java API

Хороший пример можно найти здесь .

...