为什么变量a
被更改,我该如何防止它?
a = [] # => []
b = a # => []
b << :hello # => [:hello]
p a # => [:hello]
# >> [:hello]
我看到使用克隆的响应,并想知道为什么以下工作以及在哪些情况下需要和不需要 .clone
a = "string" # => "string"
b =a # => "string"
b = "changed" # => "changed"
a # => "string"
为什么变量
a
会发生变化,我该如何防止它?a = [] # => [] b = a # => [] b << :hello # => [:hello] p a # => [:hello]
# >> [:hello]
变量a
未更改。更改变量的唯一方法是分配给它(忽略反射,如Binding#local_variable_set
(,而您没有这样做。因此,a
不会改变。
a
和b
引用的对象都会更改。但是改变对象和改变变量是两件完全不同的事情。
我看到使用克隆的响应,并想知道为什么以下工作以及在哪些情况下需要和不需要 .clone
a = "string" # => "string" b =a # => "string" b = "changed" # => "changed" a # => "string"
这是有效的,因为您从不更改对象。更改变量。
为什么对数组使用变异方法,对字符串使用重新绑定,并且仍然期望它们的行为相似?
a = "string" #⇒ "string"
b = a #⇒ "string"
b << "changed" #⇒ "stringchanged"
a #⇒ "stringchanged"
我了解,这是因为内存使用情况。
当你初始化对象时,Ruby 将首先初始化内存中的对象。然后,变量指向该内存地址。当您将此变量分配给另一个变量时,该变量也将指向该地址
例如
a = []
a.object_id # 70220203482480
b = a
b.object_id # 70220203482480
当您添加新元素时,这意味着您将值添加到在内存中初始化的数组中,调用 a
和 b
都会显示带有新元素的数组。
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)