我怎样才能将双 splat 论点折叠成虚无?

Posted

技术标签:

【中文标题】我怎样才能将双 splat 论点折叠成虚无?【英文标题】:How can I collapse double splat arguments into nothing? 【发布时间】:2015-03-05 11:07:40 【问题描述】:

在方法调用中对空数组进行 Splat 扩展可以有效地将参数减少为空(为清楚起见添加了空括号):

def foo()
end

def bar(*args)
  foo(*args)
end

bar(1) # ArgumentError, as expected
bar()  # works

但这同样不适用于哈希参数:

def baz()
end

def qux(**opts)
  baz(**opts)
end

qux # ArgumentError, **opts becomes 

我可以通过显式检查空哈希来解决这个问题:

def quux(callable, **opts)
  if opts.empty?
    callable.()
  else
    callable.(**opts)
  end
end

c = ->
quux(c) # works

但是有没有更好/更好的方法来做到这一点,或者是否计划改变这种行为?在编写barqux 时,我不知道foobaz 的签名,因为后者是类似工厂的构造函数包装器的一部分。

【问题讨论】:

为什么需要使用**opts*args 也应该与关键字参数一起使用。 我想得越久,我就越觉得这实际上可能是 Ruby 中的一个错误。如果foo(*[]) 有效,baz(**) 也应该有效。 @PatrickOscity 使用 args 很好。不知何故忘记了这一点。我今天学习了 double splat 语法,并且在使用它方面可能变得有点专心。只需使用 *args 即可适用于我刚刚尝试过的每种情况,包括可选、可选关键字和必需关键字参数的混合。所以我现在实际上不需要这个工作。但我仍然同意你的第二条评论,我认为这是不直观的,可能是无意的。我会在错误跟踪器上四处寻找并提交报告。 我认为你的直觉在这里是错误的。您希望 opts 哈希应该扩展到什么?数组 splat 运算符 * 可以 1:1 将 Array 元素转换为 普通参数列表,这对于 Hash 来说是不可能且明确的。散列的“扩展”需要一个容器对象。试试key: 123, **opts[:key, 123, **opts] 看看我的意思。 @DavidUnric 我明白你的意思,但是通过引入关键字参数,我认为我的直觉至少和你的一样合理:*[] 扩展到零位置参数,所以**应该扩展到零命名参数。可以说这取决于您的观点,但在方法调用的上下文中,有理由让它按照我预期的方式工作。 【参考方案1】:

试试下面的:

def baz()
end

def qux(**opts)
    baz(*opts)
end

qux

要详细了解 *hash 的工作原理,请尝试以下操作:

h = 
puts h # 
puts *h # nothing output 
puts **h #

【讨论】:

以上是关于我怎样才能将双 splat 论点折叠成虚无?的主要内容,如果未能解决你的问题,请参考以下文章

在普通 lisp 中展开 / splat 参数

我怎样才能使这个动画更流畅?

我怎样才能把它翻译成mysql?

我怎样才能将微服务招摇聚合成一个招摇

如果没有数据返回,我怎样才能完全隐藏jqgrid?

我怎样才能把它压缩成一个 For 循环?