为什么 ** 在 "splatting" 关键字参数时是可选的?
Why is ** optional when "splatting" keyword arguments?
给定此方法定义:
def foo(a = nil, b: nil)
p a: a, b: b
end
当我使用单个散列参数调用该方法时,散列总是隐式转换为关键字参数,无论 **
:
hash = {b: 1}
foo(hash) #=> {:a=>nil, :b=>1}
foo(**hash) #=> {:a=>nil, :b=>1}
我可以传递另一个(空)散列作为解决方法:
foo(hash, {}) #=> {:a=>{:b=>1}, :b=>nil}
但是,这看起来很笨拙
我原以为 Ruby 会像处理数组一样处理这个问题,即:
foo(hash) #=> {:a=>{:b=>1}, :b=>nil}
foo(**hash) #=> {:a=>nil, :b=>1}
并使用文字:
foo({b: 1}) #=> {:a=>{:b=>1}, :b=>nil}
foo(b: 1) #=> {:a=>nil, :b=>1}
foo(**{b: 1}) #=> {:a=>nil, :b=>1}
当前的实现看起来像一个缺陷,我期望它的工作方式似乎很明显。
这是一个被忽视的边缘案例吗?我不这么认为。没有以这种方式实施可能是有充分理由的。
请问有没有大佬解惑一下?
至于缺少**
部分:
我的猜测是,为了使方法调用简单,Ruby 总是一次将不带大括号的 key: value
形式解释为省略大括号的散列,无论它是否实际上将被解释为这样的散列或作为关键字参数。
然后,为了将其解释为关键字参数,**
隐式应用于它。
因此,如果您传递了一个显式散列,它不会对上述过程产生影响,并且有空间将其解释为实际散列或关键字参数。
当您明确通过 **
时会发生什么:
method(**{key: value})
是hash分解:
method(key: value)
then 被解释为带省略括号的散列:
method({key: value})
then 被解释为散列或关键字参数。
至于关键字参数优先于其他参数,请参见Ruby核心上的post:https://bugs.ruby-lang.org/issues/11967.
给定此方法定义:
def foo(a = nil, b: nil)
p a: a, b: b
end
当我使用单个散列参数调用该方法时,散列总是隐式转换为关键字参数,无论 **
:
hash = {b: 1}
foo(hash) #=> {:a=>nil, :b=>1}
foo(**hash) #=> {:a=>nil, :b=>1}
我可以传递另一个(空)散列作为解决方法:
foo(hash, {}) #=> {:a=>{:b=>1}, :b=>nil}
但是,这看起来很笨拙
我原以为 Ruby 会像处理数组一样处理这个问题,即:
foo(hash) #=> {:a=>{:b=>1}, :b=>nil}
foo(**hash) #=> {:a=>nil, :b=>1}
并使用文字:
foo({b: 1}) #=> {:a=>{:b=>1}, :b=>nil}
foo(b: 1) #=> {:a=>nil, :b=>1}
foo(**{b: 1}) #=> {:a=>nil, :b=>1}
当前的实现看起来像一个缺陷,我期望它的工作方式似乎很明显。
这是一个被忽视的边缘案例吗?我不这么认为。没有以这种方式实施可能是有充分理由的。
请问有没有大佬解惑一下?
至于缺少
**
部分:我的猜测是,为了使方法调用简单,Ruby 总是一次将不带大括号的
key: value
形式解释为省略大括号的散列,无论它是否实际上将被解释为这样的散列或作为关键字参数。然后,为了将其解释为关键字参数,
**
隐式应用于它。因此,如果您传递了一个显式散列,它不会对上述过程产生影响,并且有空间将其解释为实际散列或关键字参数。
当您明确通过
**
时会发生什么:method(**{key: value})
是hash分解:
method(key: value)
then 被解释为带省略括号的散列:
method({key: value})
then 被解释为散列或关键字参数。
至于关键字参数优先于其他参数,请参见Ruby核心上的post:https://bugs.ruby-lang.org/issues/11967.