Ruby 可选参数,如果更改会影响调用者吗?

4
考虑下面的 Ruby 代码,假设我从某个地方调用了 prestart 函数:
def tester(process_name, *host_list)
  hosts = []
  hosts = host_list[0]
  hosts[0] = nil
end

def prestart(process_name, *host)
  host_list = ['192.168.1.1', '192.168.1.2'] 
  puts host_list.inspect  # -> ['192.168.1.1', '192.168.1.2']
  tester(process_name, host_list)
  puts host_list.inspect  # -> [nil, '192.168.1.2']
  abort
end

它是如何变成 nil 的?这就是 Ruby 的工作方式吗?如果是的话,我该如何确保它不会影响调用者?

1个回答

3

数组是对象,因此它们是通过引用传递的。如果你想在不影响原始数组的情况下进行更改,则需要调用.dup对其进行复制。你可以在调用者或被调用的方法中执行此操作。


数组在大多数高级语言中是可变对象(除了一些纯函数式语言,那里没有任何东西是可变的)。需要注意的是,在Ruby中,与大多数高级语言不同,字符串也是可变对象。 - Idan Arye
你的意思是说,如果在上面的例子中传递字符串,它会表现得类似吗?影响调用者? - Shrinath
1
如果你改变字符串本身,比如 str[0]='e',原始字符串将会被改变。但是如果你执行 str=nil,原始字符串将保持不变,因为你只是改变了引用。此外,请注意 Ruby 中许多字符串函数都有两种变体——可变和不可变。可变的变体以 ! 结尾并更改原始字符串,而不可变的则不会更改。因此,str.reverse 将返回反转后的字符串,同时保持原始字符串不变,而 str.reverse! 将反转原始字符串。这也适用于 Ruby 中的许多其他数据结构。 - Idan Arye
在 Ruby 中,永远不会通过引用传递任何东西。Ruby 是按值传递的。始终如此。没有例外。没有如果。没有但是。 - Jörg W Mittag
@Jörg W Mittag:https://dev59.com/questions/-nI-5IYBdhLWcg3wZ3fC在这次经历之后,我已经放弃了这个项目...请现在就离开吧 :) - Shrinath
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接