double*(splat)运算符的作用是什么

Roy*_*Lee 204 ruby splat

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

def foo a, **b
  ...
end
Run Code Online (Sandbox Code Playgroud)

我知道单个*是splat运算符.什么**意思?

Dog*_*ert 355

Ruby 2.0引入了关键字参数,其**行为类似于*关键字参数.它返回一个带键/值对的哈希.

对于此代码:

def foo(a, *b, **c)
  [a, b, c]
end
Run Code Online (Sandbox Code Playgroud)

这是一个演示:

> 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}]
Run Code Online (Sandbox Code Playgroud)

  • 这完全回答了这个问题,但我有一个小的附录.就像splat操作符可以在你传递的数组上使用一样,双splat可以用在哈希上.如果`opts = {d:40,e:50}`,那么`foo 10,opts,f:60`会将`{f:60}`赋给`c`,而`foo 10,**opts,f :60`将指定`{d:40,e:50,f:60}`.为了达到第二个效果,以前你可以明确地"合并"数组. (42认同)
  • 可能值得注意的是,如果将关键字参数与关键字 splat 混合,则关键字 splat 需要位于关键字参数之后。 (3认同)

Dan*_*ski 41

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

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

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

my_method(key: "value")
Run Code Online (Sandbox Code Playgroud)

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

就像单个splat操作符捕获所有常规参数一样,但是不是数组而是获得哈希值.

现实生活中的例子:

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

def cycle(first_value, *values)
  options = values.extract_options!
  # ...
end
Run Code Online (Sandbox Code Playgroud)

这个方法可以像这样调用: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
Run Code Online (Sandbox Code Playgroud)

不可否认,如果您已经在使用ActiveSupport,那只是一个小小的改进,但对于普通的Ruby,代码可以获得相当多的简洁性.


kub*_*oon 14

另外,您可以在调用者方面使用它,如下所示:

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}
Run Code Online (Sandbox Code Playgroud)

  • 哇,double-splat与ES6的对象传播运算符类似。 (3认同)
  • 谢谢,这就是我一直在寻找的确认。 (2认同)