【问题标题】:Why does specifing a named parameter change the parameters type为什么指定命名参数会更改参数类型
【发布时间】:2021-12-07 18:33:33
【问题描述】:

我最近遇到了这个问题,我很好奇我是否错误地使用了命名参数或者更好地理解它们为什么会这样。

def test_param(b=false)
    if b
        puts 'param is true'
        puts b
        puts b.class
    else
        puts 'param is false'
        puts b
        puts b.class
    end
end

当我在 REPL 中测试这个函数时,我看到了

2.5.3 :213 > test_param(true)
param is true
true
TrueClass
 => nil
2.5.3 :214 > test_param(false)
param is false
false
FalseClass
 => nil
2.5.3 :215 > test_param(b:true)
param is true
{:b=>true}
Hash
 => nil
2.5.3 :216 > test_param(b:false)
param is true
{:b=>false}
Hash
 => nil
2.5.3 :217 >

为什么当我使用命名参数时,变量数据类型被更改为哈希,这似乎错了。

【问题讨论】:

  • 当你还没有指定所有参数时,像any_method(a: 1, b: 2)这样的东西在ruby 2上被解释为any_method({ a: 1, b: 2 }),它只在强制参数之后才算作关键字参数,ruby 3,它计算所有参数后,我知道因为I asked it some months ago,所以在你的情况下,不是“关键字参数转换”,你只是传递一个哈希
  • @saviu-u 那不正确。在 Ruby 3 中,any_method({ a: 1, b: 2 }) 将始终被视为位置参数。

标签: ruby


【解决方案1】:

与其他语言(如 Python)不同,Ruby 严格区分位置参数和关键字参数。调用方法时不能提供关键字参数作为位置参数,反之亦然。

在您的情况下,您在方法中定义了一个位置参数(即b)。在最后两个示例中,您将 Hash 传递给它。请注意,通常用于定义散列的花括号在调用方法并将散列作为其最后一个参数传递时是可选的。在较旧的 Ruby 版本中,这被用作允许/传递可选参数列表的约定,其工作方式类似于关键字参数。

由于 Hash 对象总是真实的(请记住,在 Ruby 中只有 falsenil 是虚假的),因此您始终使用条件的 if 分支并输出您在那里看到的信息。

话虽如此,如果你想在你的方法中接受关键字参数,你必须相应地定义它,例如:

def test_param(b: false)
  # ...
end

注意这里参数定义的不同。您可以从the Ruby language documentation 了解更多关于 Ruby 中的关键字参数的信息。

【讨论】:

  • 需要注意的是,在 Ruby 2 中 test_param({ b: false }) 会被转换成关键字参数。严格分离只是在 Ruby 3 中才真正添加。
  • 这在 Ruby 2.7 中已被弃用,并在 3.0 中强制执行,是的。这主要是我在回答中提到的“较旧的 Ruby 版本”,同时试图避免提供太多压倒性的细节。无论如何,即使在 Ruby 2 中,您仍然必须定义接受关键字参数的方法。
猜你喜欢
  • 1970-01-01
  • 2013-08-17
  • 2012-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-05
  • 2020-05-23
  • 2018-09-01
相关资源
最近更新 更多