Ruby 中的语法 [*a..b] 是啥意思?

Posted

技术标签:

【中文标题】Ruby 中的语法 [*a..b] 是啥意思?【英文标题】:What does the syntax [*a..b] mean in Ruby?Ruby 中的语法 [*a..b] 是什么意思? 【发布时间】:2011-08-24 07:38:21 【问题描述】:

注意:mischa 的 splat on GitHub 有很多很酷的 * 互动示例。

通过谷歌搜索,我发现了一种在 Ruby 中迭代一系列数字的方法(您的经典 C 风格 for 循环)

for (i = first; i <= last; i++) 
  whatever(i);

要做这样的事情

[*first..last].each do |i|
  whatever i
end

但是[*first..last] 语法到底发生了什么?我玩过irb,我看到了这个:

ruby-1.9.2-p180 :001 > 0..5
 => 0..5 
ruby-1.9.2-p180 :002 > [0..5]
 => [0..5] 
ruby-1.9.2-p180 :003 > [*0..5]
 => [0, 1, 2, 3, 4, 5] 
ruby-1.9.2-p180 :004 > *0..5
SyntaxError: (irb):4: syntax error, unexpected tDOT2, expecting tCOLON2 or '[' or '.'
*0..5
    ^

我在网上阅读的所有内容都讨论了一元星号对于扩展和折叠传递给方法的参数很有用,对于可变长度参数列表很有用

def foo(*bar)
  bar 
end

foo 'tater' # => ["tater"]
foo 'tater', 'tot' # => ["tater", "tot"]

我明白了,但我看不出它如何应用于上面的块示例中进行的扩展。

明确地说,我知道 Ruby 方式是迭代数组或集合,而不是使用数组长度并使用整数索引进行迭代。然而,在这个例子中,我实际上是在处理一个整数列表。 :)

【问题讨论】:

我的整个方法可能是错误的。我可能应该只是在做(first..last).each ...,但我仍然想知道那里发生了什么。 :) 也可以试试:x=*0..5;p xa=[1,2,3];b=[4,5,6];c=[*a,*b];p c (Ruby 1.9+) 您也可以使用first.upto(last) |i| ... first.step(last) |i| ... 进行迭代(其中后一种方法允许您逐步递增,而不是1) 【参考方案1】:

它被称为 splat 运算符。如果您在某些位置(如参数位置或数组)中使用它,它将扩展到其元素:

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

您不能裸露或在范围内使用它:

*a..3 # => error.
(*a..3) # => error.

当你有一个不是数组的东西时,它会返回自己:

a = 1
[*a, 3] # => [1, 3]

【讨论】:

【参考方案2】:

[first..last] 是一个仅包含 1 个范围对象的数组。 [*first..last] 是一个数组,其中包含已作为参数列表发送的该范围内的元素。 * 在参数列表的上下文中工作。

【讨论】:

【参考方案3】:
[*1..10]

是一样的
(1..10).to_a # call the "to array" method

您创建的Array 类的实例实现了Enumerable,因此您的循环可以正常工作。在定义to_a 方法的类上,您可以使用带括号的splat 运算符 语法。 Splat 的作用远不止调用 #to_a,而且值得单独使用 Google 搜索。

现在,就你而言,Range 类本身已经Enumerable,所以你可以这样做:

(first..last).each do |v| 
  ...
end

【讨论】:

以上是关于Ruby 中的语法 [*a..b] 是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 语法“A::B:A ;”是啥意思?意思是

C ++结构语法“a:b”是啥意思

JavaScript 中的 ?: 语法是啥? [复制]

ruby 代码中 if a = b 的行是啥意思? [复制]

是啥? JavaScript 中的语法是啥意思?

取 A(B) 的平均值是啥意思?