将数组传递给 ruby 函数

问题描述 投票:0回答:2

好吧,我对 ruby 如何将其参数传递给函数感到困惑。我在文档中读到 ruby 通过 value 传递,但在我的例子中,它看起来像是通过 reference 传递 问题来了:

def buble_sort(arr) 
unordered = true
while unordered
    unordered = false
    for i in (1..arr.size-1)
        if(arr[i-1] > arr[i])
            arr[i-1], arr[i] = arr[i], arr[i-1] 
            unordered = true;
        end
    end
end
arr
end

调用此方法不应修改 arr 值,因为 ruby 按值传递它。但就我而言,它确实修改了原始数组。为什么? 代码:

p "#{arr} before sort" # => "[85, -4, 1, 2, 55, 23, 0] before sort"
p buble_sort(arr) # => [-4, 0, 1, 2, 23, 55, 85]
p "#{arr} after sort" # => "[-4, 0, 1, 2, 23, 55, 85] after sort"
ruby sorting pass-by-reference pass-by-value
2个回答
2
投票

要理解这一点,您必须区分变量和该变量代表的含义。考虑以下示例:

items = [1, 2, 3]
# the variable items points to an array we just instantiated
items = [4, 5, 6]
# items now points to a new array

如果 ruby 通过引用传递参数,那么在带有接收到的参数的方法中这样做也会使调用者暴露给该方法的变量指向一个新位置

items = [1, 2, 3]
def my_method array
    array = [4, 5, 6]
    return array
end
my_method(items) # --> [4, 5, 6]
items # --> [1, 2, 3]
# if ruby passed arguments by reference, items would now be [4, 5, 6]

现在 ruby 按值传递参数,但您收到的值是对内存中与被调用传递给您的值相同位置的引用。换句话说,你得到的不是克隆、复制品,而是同一个对象。

items = [1, 2, 3]
def my_method array
    array << 4
    return array
end
my_method(items) # --> [1, 2, 3, 4]
items # --> [1, 2, 3, 4]

如果您希望您的方法对其参数没有副作用,您可以克隆它们。


0
投票

Ruby 中几乎所有东西都是对象。在方法中,对象是通过引用传递的。

a = [1,2,3,4]

a 是一个变量,其值为数组的引用。

def someMethod(b)
#...
end

someMethod(a)

这里传递的 a 的值是数组的引用,并在变量 b 中接收。这意味着 a 和 b 都具有作为数组引用的值。

def someMethod(b)
b = [4,5,6] 
end

这里 b 被分配了一个新值,该值是对新数组的引用。 a 仍然具有原始数组的引用作为值。

数组是可变的,这意味着我们可以更改数组对象的内容。

a = [1,2,3]
a[1]= 5
puts a 

将打印 [1,5,3]

所有原始对象(例如数字)都是不可变对象。

a =5

a 存储包含值 5 的整数对象的引用。

a = a +1

现在 a 存储了一个包含值 6 的整数对象的引用。包含 6 的对象与包含 5 的对象不同。之前包含 5 的对象仍然包含 5,但它的引用没有存储在任何地方。

© www.soinside.com 2019 - 2024. All rights reserved.