我怎样才能将双 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
但是有没有更好/更好的方法来做到这一点,或者是否计划改变这种行为?在编写bar
和qux
时,我不知道foo
和baz
的签名,因为后者是类似工厂的构造函数包装器的一部分。
【问题讨论】:
为什么需要使用**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 论点折叠成虚无?的主要内容,如果未能解决你的问题,请参考以下文章