为什么其中一个函数改变原始数组而不改变另一个?

时间:2017-10-08 22:05:56

标签: arrays ruby

通过查看这三个功能,我不确定我错过了什么。 这些函数的期望结果是原始数组更改值

change_this = [6, 7, 8]
array_times_two!(change_this)
change_this == [12, 14, 16] => true

以下功能执行此操作

def array_times_two!(array)
  array.map! {|x| x * 2}
end

这一个......

def array_times_two!(array)
  array.each_with_index do |element, index|
    array[index] = array[index] * 2
  end
  array
end

为什么以下函数不会像其他函数一样改变值?

def array_times_two!(array)
  array = array.map {|x| x * 2}
  array
end

第二个函数如何更改数组但第三个函数不是?

1 个答案:

答案 0 :(得分:4)

在最后一个示例中,您array作为局部变量进入。重新分配局部变量对原始变量没有影响。这是因为Ruby实际上是通过值传递的,除了令人困惑的部分是那些值通常是对象引用,或者是指针的花哨术语。

这样做的后果并不复杂:在对象上调用方法可以修改该对象的内容。重新分配变量不能。

您的方法的第一个版本可能是最好的,但您可以使它更通用,例如:

def multiply_by!(array, n = 2)
  array.map! { |v| v * n }
end

你也可以修复"最后一个版本通过使用方法调用来应用更改:

def array_times_two!(array)
  array.replace(array.map {|x| x * 2})
end

这会调用Array#replace来踩踏原始对象的内容并强制更改。当map!之类的东西存在时,它不是一个非常优雅的解决方案。