Ruby集合参考

Ruby集合参考,ruby,arrays,collections,reference,Ruby,Arrays,Collections,Reference,我想知道正常变量和集合之间的区别是什么。下面是一个正态变量的示例 a = "something" b = a a = "else" p b # => "something" 据我所知,b持有对与a相同对象的引用,字符串(对象)“某物”。因此,当a改变时,其值也会改变。或者更具体地说,当引用对象发生更改时。为什么此行为与下面的数组示例不同 string = "hello" array = [string] p array # => ["hello"] string = "somet

我想知道正常变量和集合之间的区别是什么。下面是一个正态变量的示例

a = "something"
b = a
a = "else"
p b # => "something"
据我所知,
b
持有对与
a
相同对象的引用,字符串(对象)
“某物”
。因此,当
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]
指向内存中的同一个对象。我认为指针
数组[0]
是指针
a
,就像字面上一样,不是副本或其他东西。所以,当我改变一个,它会变得到处都变。就像我写
a.upcase。但是当我写
a.upcase时
,就像
a
array[0]
不再是相同的指针。

a
b
string
array
在您的示例中都包含对对象的引用。将新值指定给其中任何一个对象时,不会更改它们正在引用的对象,而是更改引用

例如:

a = "something"
b = a
现在
a
b
正在看同一件事。但在这样做之后:

a = "else"
a
不再看
“某物”
。我们没有改变
“某物”
,只让
a
“其他”
。由于这个原因,
b
,实际上没有发生什么事情,它仍然在看
“某物”
,因此:

p b # "something"
数组
示例中也会发生同样的情况。
数组
的第一个元素查看与
字符串
相同的内容,直到您更改
字符串
查看的内容-它不更改数组,也不更改它查看的元素的值-它只更改
字符串
查看的内容


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

在ruby中(与其他流行语言相反)
String
不是不可变的,因此我们可以演示它:

a = "something"
b = a

p b # "something"
a.upcase!
p b # "SOMETHING"
以及:


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

这非常简单。如果第一个示例对您来说很清楚,那么这将回答您现在遇到的第二个困惑::-)在您的第一个示例中,
p b
将打印
“something”
而不是
“else”
。写的东西不能复制。在第一段代码的末尾,
b
返回
“something”
。谢谢Uri Agassi和@sawa oh man是的,你说得对,很抱歉,我刚刚更正了它。这个问题是在火车上写在电话上的,我猜在那里写这样的问题并不完美。你的意思肯定是字符串是可变的,因为你清楚地证明了字符串可以变异。@FrederickCheung-该死的双重否定:P,修正,thanks@UriAgassi那么它比,数组不包含变量a,而是从a中接收引用?因为如果我改变
a
的外观,
array[a]
也应该改变,因为
a==array[a]
,对吗?我的意思是
a
array[a]
实际上是一样的。或者它更像是
array[a]=a
类似于
array[b]=a
,因为在这两种情况下,它不是同一个变量?@LinusAn-否。您可以在
irb
-
a!=数组[a]
。数组保存
string
引用的副本,就像
b
保存
a
引用的副本一样。当你重新分配
a
string
b
array
(分别)时,不要在意,因为它们拥有自己的引用副本(没有改变)。@UriAgassi这就是我所寻找的答案,解释了一切。非常感谢你!
string = "hello"
array = [string]
p array # => ["hello"]

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