2

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

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

当上面没问题时,下面发生了什么?意味着为什么 a 给[]

*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]

但是无法理解上面的内容。

4

2 回答 2

2

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

有一点是,一个范围是一个单一的值,直到你将它转换为一个数组或将它分解。例如[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" ]

so *ais []and bis"hey"并且按照相同的逻辑,如果*a什么都没有,则a必须是一个空数组。同样的想法

a, *b = (1..5)

对于下一个,范围是 splatted 的,因此分配再次变得很有意义:

[*(2..4), 9, 5]
# => [2, 3, 4, 9, 5]

并再次与 splat 并行分配。下一个类似:

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

所以就像

a = 3, 4, 5

这就像

a = [3, 4, 5]
于 2013-02-22T23:16:01.200 回答
1

splat具有非常低的优先级,几乎任何事情都会在 splat 之前执行。代码飞溅,但结果被丢弃:b = *a = (1..8); p b #=> [1, 2, 3, 4, 5, 6, 7, 8]

于 2013-02-22T22:33:00.593 回答