要填充我可以编写的数组[*2..10]
,它给出了[2, 3, 4, 5, 6, 7, 8, 9, 10]
.
这是如何运作的?
该表达式2..10
使用..
运算符创建Range
对象。
通常,*
展平数组,以便将单个对象转换为方法的单个参数列表。当应用于非数组对象时,它将尝试Array
通过调用将对象转换为第一个对象to_a
。所以应用*
到它的Range
第一个调用to_a
,它返回一个位于范围内的值的数组。然后,该数组被*
.
最后,将该值列表放在方括号内[
...]
生成一个新的Array
. to_a
这与调用的结果相同Range
,但它在此过程中经历了几个额外的步骤(通过*
展平和取消展平[]
)。
请注意,在赋值的右侧,您可以不使用方括号,无论是文字(x=1,2,3
产生与 相同的结果x=[1,2,3]
)还是 splatted(x=*2..10
产生与 相同的结果x=[*2..10]
)。
如果接收器是一个数组,则splat 运算符*
将接收器的元素解包到位。如果接收者不是数组,则使用 方法提前尝试隐式类转换to_a
。
在您的情况下, range2..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]
.
或(1..5).to_a
。
还要记住,x..y
包括y
在范围内,但x...y
包括直到y
,即:
(1...5).to_a
产量[1,2,3,4]
。