gpt4 book ai didi

ruby - 为什么 Ruby splat 不适用于条件赋值中的数组强制?

转载 作者:数据小太阳 更新时间:2023-10-29 07:05:34 24 4
gpt4 key购买 nike

虽然 splat ( * ) 构造通常被称为 splat 运算符,但很明显,与其他一元运算符(如否定运算符(!)相比,它是一个不同的野兽。 ) 运算符。

splat 在赋值 (=) 中使用时,它自己可以正常工作(即不包含在括号中),但在与条件赋值(||=)一起使用时会产生错误。示例:

a = *(1..3)
#=> [1, 2, 3]

b ||= *(1..3)
SyntaxError: (irb):65: syntax error, unexpected *

我不是在寻找替代方法来做同样的事情,而是在寻找对 Ruby 内部结构有更好理解的人来解释为什么 splat 结构的这种用法在第一种情况下有效,但在第二种情况下无效。

最佳答案

这是我对 splat 的实际目标的理解。这是针对 Ruby 2.2 MRI/KRI/YARV 的。

Ruby splat 在分配期间将对象解构为数组。

a 为假时,这些示例都提供相同的结果:

a = *(1..3)
a = * (1..3)
a =* (1..3)
a = *1..3
a = * 1..3
a = * a || (1..3)
a = * [1, 2, 3]
=> [1, 2, 3]

splat 在赋值过程中进行解构,就像你这样写一样:

a = [1, 2, 3]

(注意:splat 调用#to_a。这意味着当你 splat 一个数组时,没有任何变化。这也意味着你可以为你自己的任何类定义你自己的解构类型,如果你愿意的话。)

但是这些语句失败了:

*(1..3)
* 1..3
* [1,2,3]
false || *(1..3)
x = x ? x : *(1..3)
=> SyntaxError

这些语句失败是因为在 splat 发生时没有发生赋值。

你的问题是这种特殊情况:

b ||= *(1..3)

Ruby 将其扩展为:

b = b || *(1..3)

这个语句失败了,因为在 splat 发生的时候没有赋值发生。

如果您需要在自己的代码中解决这个问题,您可以使用临时变量,例如:

b ||= (x=*(1..3))

值得一提的是:当 splat 位于表达式的左侧时,它的用法完全不同。这个 splat 是并行分配期间的低优先级贪婪收集器。

例子:

*a, b = [1, 2, 3]  #=> a is [1, 2], b is 3
a, *b = [1, 2, 3] #=> a is 1, b is [2, 3]

所以这会解析:

*a = (1..3)  #=> a is (1..3)

它将 a 设置为右侧的所有结果,即范围。

在极少数情况下,splat 可以被理解为解构器或收集器,那么解构器具有优先权。

这一行:

x = * y = (1..3)

对此的评估:

x = *(y = (1..3)) 

不是这个:

x = (*y = (1..3)) 

关于ruby - 为什么 Ruby splat 不适用于条件赋值中的数组强制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29864514/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com