8

给定

a = [[:a, :b, :c]]

1)我明白这一点

a.each{|(x, y), z| p z} # => :b

有两个变量(x, y)z,所以第三个元素:c被丢弃,并且z匹配:b。我明白这一点

a.each{|(x, y), z| p y} # => nil

(x, y)匹配,:a因为它不是一个数组,所以它没有元素,所以y匹配nil

但是怎么做

a.each{|(x, y), z| p x} # => :a

工作?我期待nil被退回。

2)为什么返回值是这样的?

a.each{|(x, y)| p x} #=> :a
a.each{|(x, y)| p y} #=> :b

我希望他们都回来nil

4

1 回答 1

12

这是因为并行赋值的语法。

a = [[:a, :b, :c]]

所以a.each只有一个元素要迭代,即[:a, :b, :c].

在第一种情况下:

(x, y), z = [:a, :b, :c]
#=> x == :a, y == nil, z == :b

(x, y)是一个匹配第一个元素的数组:a,并x获取它,然后z简单地匹配第二个元素:b

在第二种情况下:

(x, y) = [:a, :b, :c]
#=> x == :a, y == :b

这里(x, y)作为一个完整的数组匹配数组[:a, :b, :c],所以xyget分别是:a:b

这就像要求“args + optional args (keyword args) + rest args”组合匹配提供的参数一样。按顺序接受参数就足够聪明了。

另一个聪明的例子:

(a,b) = 1,2
=> [1, 2] # array match
#=> a == 1, b == 2

(a,b)=[1,2]
=> [1, 2] # array match
#=> a == 1, b == 2

在上述任何一种情况下,它都会对应该采取的措施做出最好的猜测。

于 2012-08-23T14:44:58.950 回答