#ruby
Вопрос:
Я использую Ruby для ввода строки и изменения порядка букв (так, чтобы последняя буква становилась первой и т. Д.).
Когда я использую приведенный ниже код, я случайно создаю палиндром, взяв половину строки и повторив ее:
def reverse(word)
i = 0
new_word = word
while i < word.length
new_word [i] = word [word.length - i - 1]
i = 1
end
return new_word
end
puts reverse("cat") # => "tac"
puts reverse("programming") # => "gnimmargorp"
puts reverse("bootcamp") # => "pmactoob"
Однако, когда я использую приведенный ниже код, я все делаю правильно:
def reverse(word)
i = 0
new_word = ""
while i < word.length
new_word [i] = word [word.length - i - 1]
i = 1
end
return new_word
end
puts reverse("cat") # => "tac"
puts reverse("programming") # => "gnimmargorp"
puts reverse("bootcamp") # => "pmactoob"
Я просто изменил слово на «» (строка 4), и это работает. Почему?
Я подозреваю, что сама строка (слово) меняется с каждой итерацией, но она не должна этого делать, не так ли?
Спасибо вам всем.
Ответ №1:
Я подозреваю, что сама строка (слово) меняется с каждой итерацией, но она не должна этого делать, не так ли?
Ваши подозрения верны.
new_word = word
Это не создает новую строку. Он говорит new_word
ссылаться на тот же список, word
что и . Ruby-один из немногих языков, где строки на самом деле являются изменяемыми объектами. Поэтому , когда вы изменяете new_word
с []=
помощью, вы также изменяете word
. Как вы уже заметили, вы можете начать с пустой строки
new_word = ""
В качестве альтернативы, если вы хотите начать с word
него и изменить его (безусловно, существуют некоторые алгоритмы, в которых это может быть полезно), мы можем использовать #dup
метод, который выполняет неглубокую копию данных
new_word = word.dup
Вы можете проверить, относятся ли две переменные к одному и тому же объекту (в отличие от простого внешнего вида), используя #equal?
puts(new_word.equal? word)
Комментарии:
1. Большое спасибо! Почему я должен хотеть изменить исходную строку, используя новую строку? Другими словами, почему существует эта функциональность?
2. Идея похожа на то, зачем мне менять свой оригинальный автомобиль на новый двигатель? Возможно, пользователь ожидает, что его ссылочная строка изменится с помощью вашего метода. Возможно, с моей стороны было бы глупо ожидать совершенно новую машину только для того, чтобы получить обновление.
3. Предположим, я хочу заменить все гласные вопросительными знаками в строке. Если строка составляет несколько килобайт, гораздо разумнее изменить ее на месте, чем копировать всю, когда я изменяю только небольшую ее часть.