Ruby 传递参数:Array 和 Set 之间的区别

Ruby passing arguments: difference between Array and Set

提问人:fakub 提问时间:4/24/2014 更新时间:4/24/2014 访问量:106

问:

我正在尝试将一个数组放入另一个现有数组,并将其所有项目放入现有集合中。下面是最小的示例:

require "set"

def add(myarr, bigarr, myset)
    bigarr << myarr
    myset |= Set.new(myarr)
end

bigarr = []
myset = Set.new

add([1, 2], bigarr, myset)

这会产生..好的,但是..为空。我对在 Ruby 中传递参数知之甚少(应该是按值)——在数组的情况下,值应该是对其内容的引用,那么我不知道 set 的值可能是什么。bigarr = [1, 2]myset = {}

问题是:

  1. 导致这种行为的实质区别是什么?ArraySet
  2. 有没有办法强制 Ruby 按引用传递,或者有没有其他推荐的方法来解决引用问题?

提前致谢!

Ruby 按引用传递

评论


答:

1赞 Chuck 4/24/2014 #1

这与数组和集合之间的区别没有任何关系。您正在使用该方法修改数组,但您正在使用运算符重新分配变量。你永远不会修改你传入的集合。你想要的可能是.<<myset|=myset.merge(myarr)

评论

0赞 Mike Szyndel 4/24/2014
很好的答案,我只是认为 OP 旨在使用 ,是位运算符,在这种情况下没有意义。||=|=
0赞 Chuck 4/24/2014
@MichaelSzyndel:它是按位的 Fixnums 和 Bignums,但 Set 和 Array 将其用作集合联合运算符。我认为运算符在语义上是正确的,但问题只是 OP 想要一个破坏性的操作,而不是一个。|
0赞 Mike Szyndel 4/24/2014
你能给我指出文档吗?在 Set/Array 和 Enumerable 中都看不到它。
0赞 Chuck 4/24/2014
@MichaelSzyndel集#|
1赞 Chuck 4/24/2014
@MichaelSzyndel:是的,Ruby 会以这种方式对任何操作员进行脱糖。=
1赞 Esse 4/24/2014 #2

这里的问题实际上来自这一行:

 myset |= Set.new(myarr)

在这里,您将在旧变量名称上创建新对象。您正在将一个指针替换为另一个指针,但这只会修改它的本地副本。原始对象仍将存在于内存和外部函数中,指针将指向旧对象(空集)(tbh:我真的不鼓励这种带有副作用的 ruby 编写)。

如果将其更改为

require "set"

def add(myarr, bigarr, myset)
    bigarr << myarr
    myset.add(myarr)
end

bigarr = []
myset = Set.new

add([1, 2], bigarr, myset)

它工作正常 - 因为您修改了现有对象并且没有创建新对象。

这里有一个很好的答案可以更彻底地解决这个问题:https://stackoverflow.com/a/16464640/1975116

评论

1赞 Chuck 4/24/2014
基于 ,OP 似乎想将 myarr 的内容合并到集合中,而不是添加数组本身。myset |= Set.new(myarr)
0赞 fakub 4/26/2014
没错,@Chuck的答案做了它应该做的事情。 #merge 方法修改现有实例, |= 创建新实例。谢谢,我现在明白了。