为什么单个空数组的并行赋值分配多​​个nils?

时间:2013-01-20 09:03:51

标签: ruby parallel-assignment

我想为多个变量分配一个空数组。这就是我正在做的事情:

irb(main):015:0> a, b, c = []
=> []
irb(main):016:0> a
=> nil
irb(main):017:0> b
=> nil
irb(main):018:0> c
=> nil

它给了我nil。我想知道为什么?但如果我这样做了:

irb(main):019:0> a, b, c = [], [], []
=> [[], [], []]
irb(main):020:0> a
=> []
irb(main):021:0> b
=> []
irb(main):022:0> c
=> []

然后它按照我的预期工作,但它比第一个更长一点。第一个例子出了什么问题?

4 个答案:

答案 0 :(得分:2)

我相信这个例子可以帮助您理解问题:

[1] pry(main)> a, b, c = [1,2]
=> [1, 2]
[2] pry(main)> a
=> 1
[3] pry(main)> b
=> 2
[4] pry(main)> c
=> nil

现在回到你的问题,你试图将空数组中的元素分配给变量,结果,三个变量都得到nil值。

答案 1 :(得分:1)

a = b = c = []

但请注意,所有变量都将分配相同的数组 这样:

a = b = []
b << 1
p b        # [1]
p a        # [1]

答案 2 :(得分:1)

单个Rvalue的并行分配

如果赋值包含多个左值和一个右值,则Ruby会尝试将rvalue扩展为数组,就像在rvalue上调用#to_a一样。因此,a, b, c = []示例的问题在于它在语义上等同于:

a, b, c = nil.to_a

显然会将nil分配给第一个变量,并将其他变量保留为未分配(也为零)。相反,请考虑一下:

a, b, c = 1
a
# => 1
b
# => nil
c
# => nil

同样的原则正在起作用,但是现在你可以看到第一个左眼 从右边接收一个作业;当作业没有时,它就不明显了。

答案 3 :(得分:0)

Ruby在进行并行赋值时会对数组进行解构:

a, b, c = [:foo, :bar, :baz]
a # => :foo
b # => :bar
c # => :baz

如果你给它一个条目太少的数组,它会将剩余的值设置为nil

a, b, c = [:foo, :bar]
a # => :foo
b # => :bar
c # => nil

所以你的第一个例子就是这个的自然扩展 - 一个空数组肯定有太少的条目来分配任何变量!