我想知道普通变量和集合之间的区别。这是一个普通变量的例子。
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
好的,这意味着指针a
和array[0]
指向内存中的同一个对象。我认为指针array[0]
是指针a
,就像字面上相同,而不是副本或其他东西。因此,当我改变a时,它随处可见。就像我写a.upcase!
时一样。但是当我写a.upcase!
时,它就像a
和array[0]
不再是相同的指针。
答案 0 :(得分:1)
a
,b
,string
和array
都将引用保存到对象中。为其中任何一个分配新值时,它不会更改它们引用的对象,而是更改引用。
示例:
a = "something"
b = a
现在a
和b
正在查看相同的内容。这样做之后:
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"]
在这些示例中,我们没有为a
和string
分配任何新内容,而是更改了当前分配给它们的对象的状态,并且查看该对象的所有引用也看到了变化