“:key => 'value'”和“key: 'value'”这两种哈希表表示法有什么区别吗?

141

:key => "value"(哈希箭头)和key: "value"(Ruby 1.9)表示法之间有区别吗?

如果没有区别,那么我想使用key: "value"表示法。是否有 gem 可以帮助我从:x =>转换为x:表示法?

5个回答

162

是的,它们之间有区别。这些是合法的:

h = { :$in => array }
h = { :'a.b' => 'c' }
h[:s] = 42

但是这些不是:

h = { $in: array }
h = { 'a.b': 'c' } # but this is okay in Ruby2.2+
h[s:] = 42

您也可以使用任何内容作为键名,只需使用 =>,比如:

h = { C.new => 11 }
h = { 23 => 'pancakes house?' }

但你不能这样做:

h = { C.new: 11 }
h = { 23: 'pancakes house?' }
JavaScript风格(键: 值)仅在您的哈希键都是“简单”的符号时有用(或多或少匹配/\A[a-z_]\w*\z/i,据我所知,解析器使用其标签模式来处理这些键)。
当使用MongoDB时,:$in风格符号会经常出现,因此如果您使用MongoDB,则将混合使用哈希风格。而且,如果您仅使用哈希的特定键(h[:k])而不是整个哈希(h = { ... }),则仍必须对符号使用冒号优先风格;您还必须对在哈希之外使用的符号使用前置冒号风格。 我喜欢保持一致,因此根本不使用JavaScript风格。
在Ruby 2.2中已经修复了JavaScript风格的某些问题。例如,如果您有无效标签的符号,则可以使用引号。
h = { 'where is': 'pancakes house?', '$set': { a: 11 } }

但是如果你的键不是符号,你仍然需要使用哈希火箭(=>)。


从Ruby 2.2.0开始,h = { 'a.b': 'c' }是合法的。请参见https://bugs.ruby-lang.org/issues/4276。 - B Seven
@BSeven:谢谢,我之前更新了我的另一个大的哈希箭头答案,但是错过了这个。 - mu is too short
你为什么觉得 h[:s] = 42 的例子与这个问题有关?在我看来,JavaScript 风格和 hashrocket 风格只与哈希键值对的定义相关,而不涉及通过键来寻址哈希元素。因此,h[s:] = 42 的例子似乎是误导性的。 - Nic Nilov
@NicNilov 这很相关,因为JavaScript风格涉及符号作为哈希键,而允许的符号表示法令人困惑,取决于上下文。 - mu is too short
无法同意。当使用符号来寻址哈希槽时,您始终使用h[:s] = 42的表示法。没有其他选择。只有在定义键/值对时,您才可以选择使用JavaScript风格的{ key: value }或哈希箭头风格的{ :key => value }。寻址场景似乎仍然与重点不相关。 - Nic Nilov
在 Ruby 中,“obj[:key]”和“obj["key"]”有什么不同? - MasterLuV

12

key: "value" 是 Ruby 1.9 的一个便利功能;只要您知道您的环境支持它,我认为没有理由不使用它。用冒号比用"rocket"符号更容易输入,并且我认为看起来更清爽。至于是否有用于转换的 gem,可能没有,但如果您尚未了解文件操作和正则表达式,那么这似乎是一个理想的学习经验。


8

Ruby哈希键通过哈希火箭(例如 's' => x)可以为键值对提供字符串,而通过符号进行键分配(例如 key: "value" 或者 :key => "value"无法使用字符串作为键。尽管哈希火箭为哈希表提供了自由和功能性,特别是允许字符串作为键,但如果哈希表使用符号作为哈希键构造,则应用程序性能可能会较慢。以下资源可能能够阐明哈希火箭和符号之间的任何差异:


5
key: value 的JSON风格赋值是新的Ruby1.9哈希语法的一部分,因此请记住这种语法在旧版本的Ruby中不可用。另外,键将会是符号(symbols)。如果您可以接受这两个限制,新哈希与旧哈希的工作方式完全相同; 除了样式外没有其他原因需要将它们转换。

6
请注意,这不是JSON风格,而是JavaScript风格。JSON要求键名用引号括起来。 - mu is too short

2

使用:key => value与使用key: value是一样的,只是为了方便。我没有看到其他使用=>的语言,但其他语言(如Javascript)在其哈希等效数据类型中使用key: value

至于转换哈希的gem,我建议您在当前项目中继续使用您现在的方式。

*请注意,在使用key: value时,键将是一个符号,并且要访问存储在foo哈希中该键的值仍然是foo[:key]


Perl 和 PHP 都使用 =>。我猜 Ruby 受 Perl 的重要启发,从 Perl 借用了这种语法 :) - Daniel Serodio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接