重新分配的哈希会更改原始哈希

时间:2019-06-13 23:38:14

标签: ruby

为什么变量a被更改了,我该如何避免?

a = []       # => []
b = a        # => []
b << :hello  # => [:hello]
p a          # => [:hello]

# >> [:hello]

我看到了使用克隆的响应,并且想知道为什么下面的方法有效以及在什么情况下需要和不需要.clone

a = "string"   # => "string"
b =a           # => "string"
b = "changed"  # => "changed"
a              # => "string"

3 个答案:

答案 0 :(得分:2)

  

为什么变量a被更改了,我该如何避免?

a = []       # => []
b = a        # => []
b << :hello  # => [:hello]
p a          # => [:hello]
# >> [:hello]

变量a not 更改。唯一可以更改变量的方法是分配给变量(忽略诸如Binding#local_variable_set之类的反射),而您没有这样做。因此,a不会改变。

由{em> ab分别引用对象。但是更改 object 和更改 variable 是两件事。

  

我看到了使用克隆的响应,并且想知道为什么下面的方法有效以及在什么情况下需要和不需要.clone

a = "string"   # => "string"
b =a           # => "string"
b = "changed"  # => "changed"
a              # => "string"

之所以有效,是因为您永远不会更改对象。您更改变量。

答案 1 :(得分:1)

为什么要对数组使用变异方法并为字符串重新绑定,并且仍然希望它们的行为类似

a = "string"   #⇒ "string"
b = a          #⇒ "string"
b << "changed" #⇒ "stringchanged"
a              #⇒ "stringchanged"

答案 2 :(得分:0)

据我了解,这是因为内存使用情况。

初始化对象时,Ruby将首先在内存中初始化对象。然后,变量指向该内存地址。当您将此变量分配给另一个变量时,该变量也将指向该地址

例如,

a = []
a.object_id # 70220203482480
b = a
b.object_id # 70220203482480

添加新元素时,意味着将值添加到在内存中初始化的数组,调用ab都将显示带有新元素的数组。

a.push(1)
b # [1]

让我们看第二个例子

c = 'reference'
d = c
c.object_id #70220203442960
d.object_id #70220203442960

c.capitalize! # 'Reference'
d # 'Reference'

如果您分配d = 'new object',则Ruby将在内存中创建另一个对象并将其值提供为字符串new object,然后d将指向该新内存地址

d = 'new object'
d.object_id # 70220203334840 (different one)
c # 'Reference' (cause c still point to the last object in memory)