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

你见过这样一个函数吗?

def foo a, **b ... end 

我明白单个*是摔跤运算符。 **是什么意思?

Ruby 2.0引入了关键字参数,而**作用类似于* ,但对于关键字参数。 它返回一个哈希键/值对。

对于这个代码:

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

这是一个演示:

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

这是自从Ruby 2.0以来可用的双splat运算符。

它捕获所有的关键字参数 (这也可以是一个简单的哈希,这是在成为Ruby语言之前模仿关键字参数的惯用方法)

 def my_method(**options) puts options.inspect end my_method(key: "value") 

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

就像单个的图示运算符捕获所有常规的参数,而不是一个数组,你会得到一个散列

真实的例子:

例如在Rails中, cycle方法如下所示:

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

这种方法可以这样调用: cycle("red", "green", "blue", name: "colors")

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

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

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

不可否认的是,如果您已经使用了ActiveSupport,那么这只是一个小小的改进,但对于普通的Ruby而言,代码会获得相当多的简洁性。

另外,你可以像这样在呼叫方使用它:

 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} 

对于整数,**表示指数,即2 ** 3与2 ^ 3相同

Interesting Posts