【问题标题】:What is the point of using Ruby's double-splat (`**`) in method calls?在方法调用中使用 Ruby 的 double-splat (`**`) 有什么意义?
【发布时间】:2014-05-05 09:24:57
【问题描述】:

使用单个 splat,我们可以将数组扩展为多个参数,这与直接传递数组有很大不同:

def foo(a, b = nil, c = nil)
  a
end

args = [1, 2, 3]

foo(args)  # Evaluates to foo([1, 2, 3]) => [1, 2, 3]
foo(*args) # Evaluates to foo(1, 2, 3)   => 1

但是,对于关键字参数,我看不出有什么区别,因为它们只是哈希的语法糖:

def foo(key:)
  key
end

args = { key: 'value' }

foo(args)   # Evaluates to foo(key: 'value') => 'value'
foo(**args) # Evaluates to foo(key: 'value') => 'value'

除了漂亮的对称性之外,还有什么实际理由在方法调用上使用双板? (请注意,这与在方法定义中使用它们不同)

【问题讨论】:

  • A similar question about ** 在方法的定义中包含一些相关信息。对已接受答案的评论谈到了使用 ** 对参数的影响。
  • 您应该提取该评论并将其放在这里,完美回答问题。
  • @DaniëlKnippers 是的,请这样做:)
  • 我现在在手机上,如果其他人或您自己将其发布为答案也没关系 :-)

标签: ruby syntax double-splat


【解决方案1】:

使用单个参数的示例是退化情况。

看一个不平凡的案例,您可以很快看到使用新的** 运算符的优势:

def foo (args)
  return args
end

h1 = { b: 2 }
h2 = { c: 3 }

foo(a: 1, **h1)       # => {:a=>1, :b=>2}
foo(a: 1, **h1, **h2) # => {:a=>1, :b=>2, :c=>3}
foo(a: 1, h1)         # Syntax Error: syntax error, unexpected ')', expecting =>
foo(h1, h2)           # ArgumentError: wrong number of arguments (2 for 1)

使用** 运算符允许我们在命令行中将现有的散列与文字键值参数合并在一起。 (当然,将* 与参数数组一起使用也是如此。)

遗憾的是,您必须小心这种行为,具体取决于您使用的 Ruby 版本。至少在 Ruby 2.1.1 中,有一个错误,即散布散列 would be destructively modified,尽管它已经被修补了。

【讨论】:

    猜你喜欢
    • 2019-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-10
    • 2015-02-23
    • 2017-08-25
    • 1970-01-01
    • 2011-01-08
    相关资源
    最近更新 更多