如何默认使用字符串键创建哈希表

42

当我执行以下操作时:

h = { "a": 123 }

Ruby会自动将键转换为符号。

h[:a]  # => 123
h["a"] # => nil

我该如何防止这种行为?我使用字符串键创建了哈希表,并希望保持原样,而不必总是调用Hash#stringify_keys


2
key: value 只是 :key => value 的一种简写方式,因此在您的示例中实际上没有字符串键 - "a": 123 变成了 :"a" => 123(请注意前导的 :)。 - Stefan
@Joerg:欢迎您提交功能请求 :) - Sergio Tulentsev
@SergioTulentsev请不要再给出那样的建议了。HashWithIndifferentAccess与Ruby无关 :) - Aleksei Matiushkin
@mudasobwa:你知道我知道 :) - Sergio Tulentsev
@SergioTulentsev 我知道你知道,但并不是所有读者都可能有相应的幽默感。因此,我认为最好首先将 HashWithIndifferentAccess 回溯到 Ruby 中。 - Aleksei Matiushkin
显示剩余4条评论
4个回答

63

使用哈希箭头语法:

h = { "a" => 123 }
#=> {"a"=>123}
h['a']
#=> 123

是的,我知道...但是自从使用了新的记号法 - 就再也回不去了 :) - Joerg
@Joerg 如果你想把某个对象作为键,该怎么办呢?{ Object.new => :hello } - 在新形式下没有办法编写它。新语法仅适用于符号键,其他所有内容都需要使用旧方式。 - Andrey Deineko
确实,当使用冒号时,如果字符串键被修改为符号,这可能会令人困惑/沮丧 - 这经常让我犯错。无论如何,谢谢。 - Joerg
8
Hashrocket不会消失。而且,它看起来相当不错 :) - Sergio Tulentsev
4
顺便说一下,使用带有连字的适当字体(例如Hasklig)可以使哈希火箭看起来非常酷。 - Aleksei Matiushkin
显示剩余8条评论

13

使用哈希火箭符=>代替冒号符:

h = { "a" => 123 }
#=> {"a"=>123}

现在您可以使用以下方式访问该值

h["a"]
#=> 123

顺便提一下,如果你正在使用Rails并希望确保可以使用符号和字符串键访问值

你可以使用Hash#with_indifferent_access

h = { a: 123 }.with_indifferent_access
#=> {"a"=>123}

h[:a]
#=> 123
h["a"]
#=> 123
h['a']
#=> 123

6

尝试

h = { "a" => 123 }

冒号使您的键成为符号。


5
可惜……这种丑陋的表示法……:( - Joerg

5

澄清一个误解:

当字符串键被改为符号时,这会让人感到困惑/沮丧。

一开始它就不是一个字符串。这只是创建符号键的另一种语法。考虑以下内容:

:'foo-bar'.class # => Symbol

有时,符号中可能会出现看起来完全不同的字符。

例如,上面的内容(不带引号)意思是 "创建文字符号:foo,并从中减去本地变量/方法调用结果bar"。以前,除了使用String#to_sym之外,没有其他方法可以构建这样的符号。您必须承认,这看起来很糟糕:

{'foo-bar'.to_sym => 42, :this_now_needs_rocket_notation => 'baz'}

一般而言,引号并不意味着字符串的创建,它们意味着按原样使用和/或为某物定义边界。因此,它们偶然地适用于字面字符串语法,但这并不是它们唯一的应用。


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