double * (splat)操作符是做什么的

时间:2021-09-28 22:31:04

Have you seen a function declared like this?

你见过这样声明的函数吗?

def foo a, **b
  ...
end

I understand that a single * is the splat operator. What does ** mean?

我知道一个*就是splat操作符。* *是什么意思?

3 个解决方案

#1


295  

Ruby 2.0 introduced keyword arguments, and ** acts like *, but for keyword arguments. It returns a Hash with key / value pairs.

Ruby 2.0引入了关键字参数,而**的作用类似于*,但针对关键字参数。它返回一个带有键/值对的散列。

For this code:

这段代码:

def foo(a, *b, **c)
  [a, b, c]
end

Here's a demo:

这里有一个演示:

> foo 10
=> [10, [], {}]
> foo 10, 20, 30
=> [10, [20, 30], {}]
> foo 10, 20, 30, d: 40, e: 50
=> [10, [20, 30], {:d=>40, :e=>50}]
> foo 10, d: 40, e: 50
=> [10, [], {:d=>40, :e=>50}]

#2


33  

That is the double splat operator which is available since Ruby 2.0.

这是自Ruby 2.0以来的双splat操作符。

It captures all keyword arguments (which can also be a simple hash, which was the idiomatic way to emulate keyword arguments before they became part of the Ruby language)

它捕获所有关键字参数(也可以是简单的散列,这是在关键字参数成为Ruby语言的一部分之前模拟它们的惯用方法)

def my_method(**options)
  puts options.inspect
end

my_method(key: "value")

The above code prints {key:value} to the console.

上面的代码将{key:value}打印到控制台。

Just like the single splat operator captures all regular arguments, but instead of an array you get a hash.

就像单splat操作符捕获所有常规参数一样,但得到的不是数组,而是散列。

Real-life example:

现实生活中的例子:

For example in Rails the cycle method looks like this:

例如在Rails中,循环方法是这样的:

def cycle(first_value, *values)
  options = values.extract_options!
  # ...
end

This method can be called like this: cycle("red", "green", "blue", name: "colors").

这个方法可以这样调用:cycle(“red”、“green”、“blue”、name:“colors”)。

This is quite a common pattern: You accept a list of arguments and the last one is an options hash, which can be extract - for example - using ActiveSupport's extract_options!.

这是一个相当常见的模式:您接受一个参数列表,最后一个是一个选项散列,它可以被提取——例如,使用ActiveSupport的extract_options!

In Ruby 2.0 you can simplify these methods:

在Ruby 2.0中,您可以简化这些方法:

def cycle(first_value, *values, **options)
  # Same code as above without further changes!
end

Admittedly it's only a minor improvement if you are already using ActiveSupport but for plain Ruby the code gains quite a lot of conciseness.

诚然,如果您已经在使用ActiveSupport,这只是一个小小的改进,但是对于普通的Ruby来说,代码获得了相当多的简洁性。

#3


7  

In addition, you can use it in caller side like this:

另外,您也可以在呼叫者端使用:

def foo(opts); p opts end
bar = {a:1, b:2}

foo(bar, c: 3)
=> ArgumentError: wrong number of arguments (given 2, expected 1)

foo(**bar, c: 3)
=> {:a=>1, :b=>2, :c=>3}

#1


295  

Ruby 2.0 introduced keyword arguments, and ** acts like *, but for keyword arguments. It returns a Hash with key / value pairs.

Ruby 2.0引入了关键字参数,而**的作用类似于*,但针对关键字参数。它返回一个带有键/值对的散列。

For this code:

这段代码:

def foo(a, *b, **c)
  [a, b, c]
end

Here's a demo:

这里有一个演示:

> foo 10
=> [10, [], {}]
> foo 10, 20, 30
=> [10, [20, 30], {}]
> foo 10, 20, 30, d: 40, e: 50
=> [10, [20, 30], {:d=>40, :e=>50}]
> foo 10, d: 40, e: 50
=> [10, [], {:d=>40, :e=>50}]

#2


33  

That is the double splat operator which is available since Ruby 2.0.

这是自Ruby 2.0以来的双splat操作符。

It captures all keyword arguments (which can also be a simple hash, which was the idiomatic way to emulate keyword arguments before they became part of the Ruby language)

它捕获所有关键字参数(也可以是简单的散列,这是在关键字参数成为Ruby语言的一部分之前模拟它们的惯用方法)

def my_method(**options)
  puts options.inspect
end

my_method(key: "value")

The above code prints {key:value} to the console.

上面的代码将{key:value}打印到控制台。

Just like the single splat operator captures all regular arguments, but instead of an array you get a hash.

就像单splat操作符捕获所有常规参数一样,但得到的不是数组,而是散列。

Real-life example:

现实生活中的例子:

For example in Rails the cycle method looks like this:

例如在Rails中,循环方法是这样的:

def cycle(first_value, *values)
  options = values.extract_options!
  # ...
end

This method can be called like this: cycle("red", "green", "blue", name: "colors").

这个方法可以这样调用:cycle(“red”、“green”、“blue”、name:“colors”)。

This is quite a common pattern: You accept a list of arguments and the last one is an options hash, which can be extract - for example - using ActiveSupport's extract_options!.

这是一个相当常见的模式:您接受一个参数列表,最后一个是一个选项散列,它可以被提取——例如,使用ActiveSupport的extract_options!

In Ruby 2.0 you can simplify these methods:

在Ruby 2.0中,您可以简化这些方法:

def cycle(first_value, *values, **options)
  # Same code as above without further changes!
end

Admittedly it's only a minor improvement if you are already using ActiveSupport but for plain Ruby the code gains quite a lot of conciseness.

诚然,如果您已经在使用ActiveSupport,这只是一个小小的改进,但是对于普通的Ruby来说,代码获得了相当多的简洁性。

#3


7  

In addition, you can use it in caller side like this:

另外,您也可以在呼叫者端使用:

def foo(opts); p opts end
bar = {a:1, b:2}

foo(bar, c: 3)
=> ArgumentError: wrong number of arguments (given 2, expected 1)

foo(**bar, c: 3)
=> {:a=>1, :b=>2, :c=>3}