将数组传递给 Array#each,内部使用引用或值
array1 = [0, 1]
# CASE 1:
[array1].each do |arr|
arr = [3, 4]
end
=> [0, 1]
# CASE 2:
[array1].each do |arr|
arr.delete_if { |ele| ele == 0 }
end
=> [[1]]
我认为 ruby 总是通过引用传递数组。为什么在 CASE 1 中它没有改变数组的值,但在 CASE 2 中却改变了它?谢谢。
array1 = [0, 1]
# CASE 1:
[array1].each do |arr|
arr = [3, 4]
end
=> [0, 1]
# CASE 2:
[array1].each do |arr|
arr.delete_if { |ele| ele == 0 }
end
=> [[1]]
I thought ruby always passes array by reference. Why didn't it change the value of array in CASE 1 but did change it in CASE 2? thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在第一种情况下,您所做的只是更改 arr 指向的对象 - 您实际上并未修改原始对象。这可以通过以下脚本来证明:
哪些输出...
那么案例 2 有何不同?在情况 2 中,您实际上调用了一个自毁性方法,该方法将对
arr
引用的原始对象进行更改In your first situation, all you've done is change which object
arr
points at - you haven't actually modified the original. This can be proven with the following script:Which outputs...
So how is that different in Case 2? In case 2, you're actually calling a self-destructive method, which will make changes to the original object that is being referenced by
arr
我认为你的问题与范围有关。
do-end
构造实际上是一个新块,因此当您声明arr = [3, 4]
时,您正在实例化一个新的arr = [3, 4 ]
在该块内。而在情况 2 中,您直接修改引用。在案例 1 中做同样的事情会是这样的:I think your issue has to do with scope. The
do-end
construct is really a new block, so when you declarearr = [3, 4]
you are instantiating a newarr = [3, 4]
within that block. Whereas in Case 2 you are modifying the reference directly. To do the same thing in Case 1 would be something like:.each
只是依次调用该块及其所调用的集合的每个元素(在本例中为[array1]
)。传递参数只是将其分配给参数。您的示例可以简化为以下内容:.each
simply calls the block with each element of the collection it's called on (in this case[array1]
) in turn. Passing an argument just assigns it to a parameter. Your example can be simplified to the following: