【问题标题】:Ruby Collection Reference [closed]Ruby 集合参考 [关闭]
【发布时间】:2014-07-30 06:21:22
【问题描述】:

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

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] 不再是同一个指针了。

【问题讨论】:

  • 这很简单。如果第一个例子对你来说很清楚,那将回答你现在的第二个困惑。 :-)
  • 在您的第一个示例中,p b 将打印 "something" 而不是 "else"
  • 我没有投反对票,而是投了赞成票。所写的内容无法复制。在第一块代码的末尾,b 返回"something"
  • 谢谢 Uri Agassi 和 @sawa 哦,伙计,你是对的,对此感到抱歉,我刚刚更正了。这个问题是在火车上写在手机上的,估计在那儿写这样的问题并不完美。

标签: ruby arrays collections reference


【解决方案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 分配任何新内容,而是更改了当前分配给它们的对象的状态,所有查看该对象的引用也会看到更改。

【讨论】:

  • 当然你的意思是字符串是可变的,因为你清楚地证明了一个字符串是可以改变的。
  • @FrederickCheung - 该死的双重否定:P,已修复,谢谢
  • @UriAgassi 那么它比the array doesn't hold the variable a, but takes over the reference from a 正确吗?因为如果我改变a 的内容,array[a] 也应该改变,因为a == array[a],对吧?我的意思是aarray[a] 实际上是相同的。还是更像 array[a] = a 类似于 array[b] = a 因为在这两种情况下它不是同一个变量?
  • @LinusAn - 不,你可以在irb - a != array[a] 中查看。该数组保存string引用副本,就像b 保存a 引用的副本一样。当您重新分配 astringbarray(分别)时,它们并不在意,因为它们拥有自己的引用副本(没有改变)。
  • @UriAgassi 这就是我一直在寻找的答案,它解释了一切。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-20
  • 1970-01-01
  • 1970-01-01
  • 2012-11-22
  • 2010-10-26
  • 1970-01-01
  • 2023-03-24
相关资源
最近更新 更多