1

要填充我可以编写的数组[*2..10],它给出了[2, 3, 4, 5, 6, 7, 8, 9, 10].

这是如何运作的?

4

3 回答 3

9

该表达式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])。

于 2013-09-01T18:54:29.420 回答
2

如果接收器是一个数组,则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].

于 2013-09-01T23:39:49.177 回答
0

(1..5).to_a

还要记住,x..y包括y在范围内,但x...y包括直到y,即:

(1...5).to_a

产量[1,2,3,4]

于 2013-09-01T19:06:11.890 回答