为啥哈希中的这个字符串键被转换为符号?

Posted

技术标签:

【中文标题】为啥哈希中的这个字符串键被转换为符号?【英文标题】:Why is this string key in a hash converted to a symbol?为什么哈希中的这个字符串键被转换为符号? 【发布时间】:2016-07-30 13:36:27 【问题描述】:

使用 Ruby 2.3:

在示例 1 中,字符串键 "a" 自动转换为符号,而在示例 2 中,它保持为字符串。

示例 1

"a": 1
# => :a=>1 

示例 2

"a"=>"c"
# => "a"=>"c"

我认为: 与旧式哈希火箭=> 语法相同。到底是怎么回事?为什么我从未在 Rails 中注意到这一点?是 HashWithIndifferentAccess 掩盖了这一点吗?

【问题讨论】:

@Zabba 为什么需要添加那个版本?它仅适用于最近的 Ruby。如果 OP 说它有效,则意味着它是最新版本。 OP 在问题中提到了该版本,因此删除它是不合适的,因为删除它会改变问题的含义和意图,所以在这里只是原创。 不是字符串键,是符号键。没有任何改变。 【参考方案1】:

在 Ruby 2.3(.0) 中,这些都是一样的:

:"a" => 1
"a": 1,
:a => 1
a: 1 

它们都翻译成同一个东西:a 在所有这些情况下都是一个符号。

"a"=>1 不同:a 在这种情况下是一个字符串。

【讨论】:

【参考方案2】:

这是因为 ruby​​ 1.9 引入了新的哈希语法。带有冒号的语法仅适用于符号键。它被称为“对象的符号”哈希,它只是最常见的哈希样式的语法糖。对我来说还有一点,它更接近 javascript 对象表示法。

如果我有混合键类型,那么我更喜欢旧样式(散列火箭语法),但这取决于你。混合这两种风格在我看来很难看。

【讨论】:

这不是 ruby​​ 1.9 中引入的语法。 @sawa 新语法是在 ruby​​ 1.9 中引入的,它更接近于 javascript 表示法。 我还可以在这里补充一点,"a": 1 表示法 看起来 与 JSON 完全一样,但行为却不像它。在 ruby​​ 中,我们有符号,"a": 转换为 Ruby 符号(不是字符串);在 Javascript 中我们没有符号,所以在 "a":1 的 JSON 版本中,“a”是一个字符串。因此,尽管有问题的 Ruby 哈希表示法看起来像 JSON,但从技术上讲并不相同。 @sawa 我不需要比你知道的更多。我只知道基础 @Reyko,如果你想知道,sawa 的 LOL 有点像 this。【参考方案3】:

根据Ruby documentation:

Blockquote Symbol 对象表示 Ruby 解释器中的名称和一些字符串。它们是使用 :name 和 :"string" 文字语法以及各种 to_sym 方法生成的。 [...]

这意味着运行:

$ ruby -e ruby -e "h = key: \"value\"; puts h"
$ ruby -e ruby -e "h = :key => \"value\"; puts h"
$ ruby -e ruby -e "h = \"key\": \"value\"; puts h"
$ ruby -e ruby -e "h = :\"key\" => \"value\"; puts h"
$ ruby -e ruby -e "h = \"#:key\": \"value\"; puts h"

会产生同样的结果:

$ :key=>"value"

【讨论】:

以上是关于为啥哈希中的这个字符串键被转换为符号?的主要内容,如果未能解决你的问题,请参考以下文章

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

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

为啥 Ruby 象征着我的哈希键?

为啥字典键被转换为继承的类类型?

使用 Oj.dump 序列化时将符号转换为字符串

为啥隐式符号到字符串的转换会导致 JavaScript 中的 TypeError?