为啥关键字参数必须作为带有符号键的哈希传递,而不是 Ruby 中的字符串键?

Posted

技术标签:

【中文标题】为啥关键字参数必须作为带有符号键的哈希传递,而不是 Ruby 中的字符串键?【英文标题】:Why keyword arguments must be passed as hash with symbol keys, not string keys in Ruby?为什么关键字参数必须作为带有符号键的哈希传递,而不是 Ruby 中的字符串键? 【发布时间】:2015-04-13 03:49:15 【问题描述】:

我们不能将关键字参数作为带有字符串键的散列传递,关键字参数仅适用于作为符号键的散列。

一个简单的例子:

def my_method(first_name:, last_name: )
  puts "first_name: #first_name | last_name: #last_name"
end

my_method( last_name: 'Sehrawat', first_name: 'Manoj') 
#=> first_name: Manoj | last_name: Sehrawat

my_method( first_name: 'Bob', last_name: 'Marley')
#=> first_name: Bob | last_name: Marley

my_method( 'first_name' => 'Kumar', 'last_name' => 'Manoj')
#=> Error: missing keywords: first_name, last_name (ArgumentError)

背后的原因是什么?

【问题讨论】:

我觉得思路类似于***.com/questions/8189416/… @freemanoid 我不这么认为。在这种情况下,语法是关于如何接受局部变量。不涉及任何符号。 【参考方案1】:

*** 的实现可能是相关的:

def gather_arguments(*arguments, **keywords)
  puts "arguments: #arguments.inspect"
  puts " keywords: #keywords.inspect"
end

gather_arguments('foo' => 1, bar: 2, 'baz' => 3, qux: 4)

输出:

arguments: ["foo"=>1, "baz"=>3]
 keywords: :bar=>2, :qux=>4

【讨论】:

你是说字符串键是保留的,以便它们可以区分形式关键字参数并解释为哈希参数的一部分?如果是这样,我不同意。 @sawa 我不是说这就是原因。只是 *** 的当前行为会改变(并且可能会破坏现有代码),如果允许带有字符串键的关键字参数。【参考方案2】:

简短的版本是因为 Matz 这么说 - 在这个红宝石上 issue he cmets

我对这个提议持否定态度。我的观点是你不应该(或不再)使用字符串作为关键字。

这个实际问题是围绕由此而发生的事情,但如果马茨说不,那不太可能发生。不知道他有没有进一步阐述他反对的原因。

【讨论】:

【参考方案3】:

尽管关键字参数可以在哈希中传递,但我认为主要的用途是直接使用key: value 语法:

my_method(first_name: 'Bob', last_name: 'Marley')

就这种形式而言,这里没有符号键(或数组键)。 key: value 语法是直接表示关键字参数。

我的猜测是,由于这种语法与带有符号键和省略大括号的哈希一致,因此通过带有符号键的哈希来接受关键字值对也是有意义的。并且可能是这样设计的,以便与使用符号键传递哈希的技巧兼容,该技巧在引入此语法之前使用。

【讨论】:

1.9 中的symbol: key 语法确实是专门作为向“真实”关键字参数的迁移路径引入的。

以上是关于为啥关键字参数必须作为带有符号键的哈希传递,而不是 Ruby 中的字符串键?的主要内容,如果未能解决你的问题,请参考以下文章

传递哈希而不是方法参数[关闭]

如何将带有对象作为键的 Ruby 哈希对象作为 Map 对象发送到前端 Javascript

将“void”作为函数参数传递

为啥要使用字符串键对符号进行哈希处理

作为参数的函数是不是必须按值传递? [复制]

为啥将 Collections.emptySet() 与泛型一起使用在赋值中而不是作为方法参数?