Ruby Collection Reference

时间:2014-07-30 06:21:23

标签: ruby arrays collections reference

我想知道普通变量和集合之间的区别。这是一个普通变量的例子。

a = "something"
b = a
a = "else"
p b # => "something"

据我所知,b拥有与a相同的对象的引用,即字符串(对象)"something"。因此,a更改时其值会发生变化。或者更具体地说,当引用的对象发生变化时。为什么这种行为与以下数组示例不同?

string = "hello"
array = [string]
p array # => ["hello"]

string = "something else"
p array # => ["hello"]

关闭,因为我可以认为数组不包含变量a,但接管来自a的引用并转储包含引用的变量(a)。因此,当a更改时,它对数组没有影响,因为它没有更改基础变量。

这是如何工作的?

更新 更清楚我的意思:

a = 'hello'
array = [a]
p a.object_id # 2168500580
p array[0].object_id # 2168500580

好的,这意味着指针aarray[0]指向内存中的同一个对象。我认为指针array[0]是指针a,就像字面上相同,而不是副本或其他东西。因此,当我改变a时,它随处可见。就像我写a.upcase!时一样。但是当我写a.upcase!时,它就像aarray[0]不再是相同的指针。

1 个答案:

答案 0 :(得分:1)

示例中的

abstringarray都将引用保存到对象中。为其中任何一个分配新值时,它不会更改它们引用的对象,而是更改引用。

示例:

a = "something"
b = a

现在ab 正在查看相同的内容。这样做之后:

a = "else"

a不再关注"something"。我们没有更改"something",只是告诉a查看"else"。出于这个原因 - b没有发生任何事情 - 它仍然关注"something",所以:

p b # "something"

array示例也是如此。 array的第一个元素会查看string所看到的相同内容,直到您更改string所看到的内容 - 它不会更改数组,或者它所看到的元素的价值 - 它只是改变了string所看到的


要复制您认为应该发生的事情,对象本身必须改变。

在ruby中(与其他流行语言相反)String 不可变,所以我们可以证明它:

a = "something"
b = a

p b # "something"
a.upcase!
p b # "SOMETHING"

string = "hello"
array = [string]
p array # => ["hello"]

string.upcase!
p array # => ["HELLO"]

在这些示例中,我们没有为astring分配任何新内容,而是更改了当前分配给它们的对象的状态,并且查看该对象的所有引用也看到了变化