Ruby:数组通过引用传递给函数? [复制]
Posted
技术标签:
【中文标题】Ruby:数组通过引用传递给函数? [复制]【英文标题】:Ruby: array is being passed by reference into function? [duplicate] 【发布时间】:2017-06-02 20:56:39 【问题描述】:下面有一个简单的代码
def testarray
arr_tree = [1,2,3,4,5]
(1..3).each do |index|
abcde(arr_tree)
puts arr_tree[0]
end
end
def abcde(node_tree)
node_tree[0] += 100
end
所以在 testarray 函数中,我有一个数组 arr_tree
,它被传递给函数 abcde
。我在abcde
函数中更改数组的值并在testarray
中打印数组,我在这里得到了更改后的值。所以输出是
101
201
301
但我期待
1
1
1
请解释为什么结果是这样的?还有我怎样才能达到我的预期效果?
【问题讨论】:
【参考方案1】:你的假设是错误的:ruby 不是 pass-by-reference,它始终是pass-by-value。您可以通过运行这个简单的测试轻松地验证这一点:
def foo(bar)
bar = 'reference'
end
baz = 'value'
foo(baz)
puts "Ruby is pass-by-#baz"
# Ruby is pass-by-value
更准确地说,Ruby 是call-by-object-sharing(也称为call-by-object和call-by-sharing),是的一个特例>按值传递,其中传递的值始终是指向(可能)共享(可能)可变对象的指针:
def is_ruby_pass_by_value?(foo)
foo.replace('More precisely, it is call-by-object-sharing!')
foo = 'No, Ruby is pass-by-reference.'
end
bar = 'Yes, of course, Ruby *is* pass-by-value!'
is_ruby_pass_by_value?(bar)
p bar
# 'More precisely, it is call-by-object-sharing!'
但是,这实际上与您的问题无关。它与 pass-by-reference 与 pass-by-value 无关。
所以在 testarray 函数中,我有一个数组
arr_tree
,它被传递给函数abcde
。我在abcde
函数中更改数组的值并在testarray
中打印数组我在这里得到更改后的值。
你得到改变的价值是因为你改变了价值。就这么简单。 Ruby 不是纯函数式编程语言,它确实具有可变状态。如果你改变那个状态,那么旧的状态就消失了,只有新的状态存在。
你自己写的:
我改变了数组的值
好吧,如果你改变数组,数组就会改变!整个代码中只有一个数组。
请解释一下为什么会出现这样的结果?
数组改变是因为你改变了数组。
还有我怎样才能达到我的预期效果?
你可以通过不改变数组来实现你的结果:
def testarray
arr_tree = [1, 2, 3, 4, 5]
(1..3).each do |index|
abcde(arr_tree)
puts arr_tree[0]
end
end
def abcde(node_tree)
[node_tree.first + 100, *node_tree.drop(1)]
end
【讨论】:
【参考方案2】:在 Ruby 中,一切都“作为对象传递”。
数组是对象。
如果你想避免副作用,请复制参数
def abcde(node_tree)
copy = node_tree.dup
copy[0] += 100
copy
end
请注意,由于您将变量命名为 tree
,因此 dup
方法仅生成浅拷贝。浅意味着复制数组而不是复制其元素。
为什么我上面没有说“通过引用传递”?
“通过引用传递”是另一种语言的概念,在 Ruby 的上下文中没有意义。从技术上讲,Ruby 的本机实现使用按值传递,其中值是指向对象结构的指针。然而,将 Ruby 视为使用“按值传递”是一种误导,因为它不会在将数据结构传递给函数之前创建数据结构的副本。这似乎是你认为会发生的事情……
【讨论】:
“按引用传递”意味着为变量分配另一个值也会改变调用者范围内的变量,例如node_tree = []
。这是 Ruby 不允许的。
对不起,这是错误的。 Ruby 不是通过引用传递的。
当您在 Ruby 中说“通过引用传递”时,意味着您尝试将 C++ 概念应用于错误的语言。
通过引用传递仍然是错误的,即使是引号。
点了,你们俩,更新了。以上是关于Ruby:数组通过引用传递给函数? [复制]的主要内容,如果未能解决你的问题,请参考以下文章