将数组传递给 ruby 函数

Passing array to ruby function

提问人:dev-cyprium 提问时间:4/11/2016 更新时间:9/10/2023 访问量:12030

问:

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

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 排序 按引用传递

评论

6赞 Dave Newton 4/11/2016
引用是一个值。除非复制阵列,否则您将在同一阵列上运行。
2赞 anquegi 4/11/2016
Ruby 是通过引用传递还是按值传递的可能副本?
0赞 Nick Roz 4/11/2016
您需要复制一个对象或构造一个新对象,例如。def buble_sort(*arr)
0赞 Jörg W Mittag 4/12/2016
这与按引用传递或按值传递没有任何关系。两者之间的差异只有在重新绑定引用时才能观察到,但你从不这样做,所以无论 Ruby 是按引用传递还是按值传递,结果实际上都是相同的。你所看到的只是可变状态。Ruby 不是一种纯粹的函数式语言,它具有可变状态和副作用。这是可变状态的一个例子,这也是为什么应该避免它的一个例子。

答:

2赞 VonD 4/11/2016 #1

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

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赞 Manish Shrotriya 9/10/2023
在 Java、JavaScript 和 Ruby 中,所有变量都是按值传递的。由于每个变量都包含对象的引用,因此调用的方法接收引用的副本。现在有两个变量,一个包含对原始对象的引用,第二个也包含同一对象的引用。任何对象变更操作都将通过这两个变量看到。由于复制了相同的引用并将其分配给方法参数,因此称为“按引用传递”。
0赞 Manish Shrotriya 9/10/2023 #2

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,但其引用不存储在任何位置。