双*(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相同