2017-10-08 55 views
2

通過查看這三個函數,我不確定我錯過了什麼。 這些函數的期望的結果將是原始陣列變化值,從而爲什麼這些函數之一改變原始數組而不是另一個?

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 

如何在第二個函數變化的數組,但第三個是不是?

回答

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!之類的東西時,這不是一個非常優雅的解決方案。

相關問題