要填充数组我可以写[*2..10]
,这会给[2, 3, 4, 5, 6, 7, 8, 9, 10]
。
这是如何工作的?
答案 0 :(得分:9)
表达式2..10
使用..
运算符创建Range
对象。
通常,*
会使数组变平,以便将单个对象转换为方法的各个参数列表。当应用于非数组对象时,它将首先通过调用Array
来尝试将对象转换为to_a
。因此,将*
应用于Range
首先调用to_a
,它会返回范围内的值数组。然后,*
将该数组展平为值列表。
最后,将该值列表放在方括号[
... ]
中会生成新的Array
。这与仅在to_a
上调用Range
的结果相同,但它在整个过程中经历了几个额外的步骤(按*
展平并且[]
不展平。)< / p>
请注意,在作业的右侧,您可以不使用方括号,无论是文字(x=1,2,3
产生与x=[1,2,3]
相同的结果)还是splatted(x=*2..10
收益率与x=[*2..10]
)相同的结果。
答案 1 :(得分:2)
如果接收器是阵列,则splat运算符*
将接收器的元素解包到位。如果接收器不是数组,则使用方法to_a
预先尝试隐式类转换。
在您的情况下,范围2..10
不是数组,因此尝试to_a
,因为Range#to_a
已定义,所以会成功,并提供[2, 3, 4, 5, 6, 7, 8, 9, 10]
。 splat运算符在外部[]
内解包该数组的元素,从而生成[2, 3, 4, 5, 6, 7, 8, 9, 10]
。
答案 2 :(得分:0)
或(1..5).to_a
。
另请注意,x..y
在范围内包含y
,但x...y
包括y
,即:
(1...5).to_a
收益[1,2,3,4]
。