语法 [*a..b] 在 Ruby 中意味着什么?

发布于 2024-11-07 01:01:04 字数 1051 浏览 1 评论 0原文

注意:mischa 的 GitHub 上的 splat 有很多很酷的交互式示例* 在行动中。

通过谷歌搜索,我发现在 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 Way 是迭代数组或集合,而不是使用数组长度并使用整数索引进行迭代。然而,在这个例子中,我实际上正在处理一个整数列表。 :)

NOTE: mischa's splat on GitHub has lots of cool interactive examples of * in action.

By googling, I found that one way to iterate over a range of numbers in Ruby (your classic C-style for loop)

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

is to do something like this

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

But what exactly is going on with that [*first..last] syntax? I played around with irb and I see this:

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
    ^

Everything I've read online discusses the unary asterisk as being useful for expanding and collapsing arguments passed to a method, useful for variable length argument lists

def foo(*bar)
  bar 
end

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

and I get that, but I don't see how it applies to the expansion being done in my block example above.

To be clear, I know that The Ruby Way is to iterate over an array or collection, not to use the array length and iterate with an integer index. However, in this example, I really am dealing with a list of integers. :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沧桑㈠ 2024-11-14 01:01:04
[*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
[*1..10]

is the same thing as

(1..10).to_a # call the "to array" method

Instances of the Array class you have created implement Enumerable so your loop works. On classes that define a to_a method, you can use the splat operator syntax with brackets. Splat does a lot more than just call #to_a though, and would be worth a Google search on its own.

Now, in your case, the Range class itself is already an Enumerable so you could just do:

(first..last).each do |v| 
  ...
end
诗酒趁年少 2024-11-14 01:01:04

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

[first..last] is an array containing only 1 range object. [*first..last] is an array containing the elements of that range having been sent in as an argument list. * works in the context of an argument list.

暖风昔人 2024-11-14 01:01:04

它被称为 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]

It is called a splat operator. If you use it within certain positions like an argument position or an array, it will expand into its elements:

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

You can't use it bare or in ranges:

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

When you have something that is not an array, it returns itself:

a = 1
[*a, 3] # => [1, 3]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文