此代码(在Ruby 1.9中)
word = 'atf'
new_word = word
word[0] = 'w'
puts new_word
给出响应“wtf”,这个
word = 'ok'
new_word = word
word = 'wft'
puts new_word
给出响应“ok”,这是我所期待的更多。这是Ruby中的一个错误,或者我错了,我希望改变它,但是我改变它,不应该改变new_word。
答案 0 :(得分:3)
在第一个示例中,只有一个实际的字符串对象,并且您有两个引用它的变量名称。因此,修改字符串会修改每个变量。你可以这样做:
new_word = word.dup
制作副本。
答案 1 :(得分:1)
word[0] = 'w'
是对word
变量引用的对象的方法调用。
word = 'wft'
是变量赋值。
答案 2 :(得分:1)
如在其他答案中所述,您将变量指向同一个字符串对象。
''请重新启动'':Ruby永远不会通过分配(或返回或传递给函数)来复制/复制对象。因此,如果您来自C / C ++,Ruby只能使用引用/指针。 (如果你来自Java:行为与Java非原语非常相似)。
例如:
a = [1, 2]
b = a
b << 3
puts a.inspect
# prints [1, 2, 3]
如果你不习惯,可能会更加困惑:
def foo(x)
x << 3
return nil
end
a = [1, 2]
foo(a)
foo(a)
puts a.inspect
# prints [1, 2, 3, 3]
在某些情况下,Ruby提供了两种具有相同功能的方法,一种更改实际对象,另一种返回包含更改的新对象。
例如String#gsub(from, to)
返回一个包含这些更改的新String,另一方面String#gsub!(from,to)changes the string itself. Another example would be
Array#reject vs.
Array#reject!`< / p>
Object#dup
复制一个对象(但不是它的嵌套对象)。
请注意:在大多数情况下,不修改字符串被认为是好风格
答案 3 :(得分:0)
需要注意的重要事项是:
new_word = word
分配不将 word
的值复制到new_word
。它设置使变量new_word
指向相同的内存地址作为变量word
。
因此,new_word[0] = 'x'
和word[0] = 'x'
对>> <{1}}和new_word
的值具有相同的效果。
您可以通过执行以下操作来解决问题:
word
或
new_word = word.dup
new_word = word.clone
和clone
在值变量的内存中创建副本,并返回对该内存的引用,然后是分配给dup
。 new_word
和clone
之间存在差异,但这些差异超出了您的问题范围。
此外,您会发现许多语言都以这种方式运行。例如,您可以在C#或javascript中尝试相同的语义,并看到相同的行为。