1

这段代码(在 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

给出了“好的”响应,这比我所期望的要多得多。这是 Ruby 中的一个错误,还是我错误地期望改变 word,但我改变它,不应该改变 new_word。

4

4 回答 4

3

在第一个示例中,只有一个实际的字符串对象,并且您有两个引用它的变量名。因此,修改字符串会修改每个变量。你可以改为:

new_word = word.dup

制作副本。

于 2013-03-14T15:31:31.047 回答
1

word[0] = 'w'word是对变量引用的对象的方法调用。

word = 'wft'是变量赋值。

于 2013-03-14T15:32:52.273 回答
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#gsub!(from, to) changes the string itself. Another example would beArray#reject vs.Array#reject!`

Object#dup复制一个对象(但不复制它的嵌套对象)。

请注意:在大多数情况下,不修改字符串被认为是好的样式

于 2013-03-14T15:44:01.380 回答
0

需要注意的重要一点是:

new_word = word

赋值不会复制into的 。它设置使变量指向与变量相同的内存地址wordnew_wordnew_wordword

因此,new_word[0] = 'x'和将对变量和的word[0] = 'x'产生相同的影响。new_wordword

您可以通过以下任一方式解决问题:

new_word = word.dup 

或者

new_word = word.clone

clone并在内存中dup创建变量值的副本,并返回对该内存的引用,然后将其分配给. 和之间存在差异,但它们超出了您的问题范围。new_wordclonedup

此外,您会发现许多语言都以这种方式运行。例如,您可以在 C# 或 javascript 中尝试相同的语义,并看到相同的行为。

于 2013-03-14T15:42:51.673 回答