与splat运算符和Ruby中的Range混淆

时间:2013-02-22 22:15:45

标签: ruby

我试图了解splat运算符如何与Ruby中的range一起使用。为此,我在IRB中运行了以下代码:

*a = (1..8)
#=> 1..8

当上述情况好的时候,下面发生了什么?表示为什么给出[]

*a,b = (1..8)
#=> 1..8
b
#=> 1..8
a
#=> []

表示为什么b给出[]?

a,*b = (1..8)
#=> 1..8
a
#=> 1..8
b
#=> []

以下Rvalues中的优先顺序是什么?

 a,*b = *(2..8),*3,*5
# => [2, 3, 4, 5, 6, 7, 8, 3, 5]
 b
# => [3, 4, 5, 6, 7, 8, 3, 5]
 a
# => 2

这是对splat运算符(*)的另一种尝试: -

虽然我知道在并行分配中我们不能使用多个splatted变量,但是当splat与Rvalues一起使用时为什么不一样?

 *a,*b = [1,2,3,4,5]
SyntaxError: (irb):1: syntax error, unexpected tSTAR
*a,*b = [1,2,3,4,5]
    ^
    from /usr/bin/irb:12:in `<main>'

以上是预期的。

 a = *2,*3,*5
#=> [2, 3, 5]

但无法理解上述内容。

2 个答案:

答案 0 :(得分:1)

splat的优先级非常低,几乎任何事情都会比splat更早执行。 代码是splatting但结果被抛弃:b = *a = (1..8); p b #=> [1, 2, 3, 4, 5, 6, 7, 8]

答案 1 :(得分:1)

我认为将并行赋值设置为等于具有模式匹配的另一个数组的变量数组。

有一点是,在将范围转换为数组或将其展开之前,范围是单个值。例如[1..5],它是范围1..5而不是[1,2,3,4,5]的单元素数组。要获得整数数组,您需要执行(1..5).to_a[*(1..5)]


我认为第一个是最棘手的。如果将splatted var分配给一个元素,则var本身必须是一个单元素数组:

*a = 5
a 
# => [ 5 ]

对于接下来的两个,splat将0或更多尚未指定的值赋入数组。所以以下是有道理的:

*a, b = (1..8)

就像

*a, b = "hey"

就像

*a, b = [ "hey" ]

因此*a[]b"hey",并且假设*a为空,a必须为a, *b = (1..5) 空数组。

的想法一致
[*(2..4), 9, 5]
# => [2, 3, 4, 9, 5]

对于下一个,范围是splatted,所以分配再次有意义:

[*3, *4, *5]
# => [3, 4, 5]

再次使用splat进行并行分配。下一个是类似的:

a = 3, 4, 5

这就像

a = [3, 4, 5]

就像

{{1}}