Ruby中的"=>和":"是什么?

4

在 Ruby 中定义 Hash 时,有几种不同的语法可供选择:

# IRB Ruby 2.7.1 - Defining a Hash
my_hash = { 'string_transformed_into_symbol_1': 'value',
            "string_transformed_into_symbol_2": 'value',
            'string_1' => 'value',
            "string_2" => 'value',
            symbol_1: 'value',
            :symbol_2 => 'value' }

我想箭头=>是Ruby 1.8版本的语法,被冒号:所替代。但是,从上面的例子中我们可以看到,它不仅仅是一种语法糖:冒号:将一个键String转化为Symbol
# IRB Ruby 2.7.1 - Outputing a Hash
my_hash
=> { :string_transformed_into_symbol_1 => "value",
     :string_transformed_into_symbol_2 => "value",
     "string_1" => "value",
     "string_2" => "value",
     :symbol_1 => "value",
     :symbol_2 => "value" }

来自这篇问题,mu is too short发布了一份很好的回答:

如果你的Hash键都是简单的符号(大致上匹配于/\A[a-z_]\w*\z/i),那么JavaScript风格的写法(key: value)会很有用 [...] 但如果你的键不是一个符号,那么你仍需要使用hashrocket。

这让我认为:=>是方法(但是我知道我是错的)。然而,我在文档中找不到关于它们的任何信息。

问题:到底:=>是些什么东西?我该怎样更多地了解它们,在Ruby源代码中它们定义在何处?


Literals > Hashes 介绍了哈希字面量的语法。 - Stefan
它们是由词法分析器/语法分析器使用的标记。我在下面提供了更详细的解释。 - Todd A. Jacobs
2个回答

4

词法/语法分析器标记

您所引用的符号不是方法或运算符,而是用于解释源代码语法的词法/语法分析器标记。哈希箭头被定义为tASSOC关联标记,用于关联键值对或异常堆栈跟踪等内容。

在Ruby中,冒号有多种用途,但我IRC Ruby 2.x引入了后缀冒号作为语法糖,当左侧为Symbol时,用于表示tASSOC。对于复杂情况下该标记的定义或解析方式,我不太确定- assoc 最可能用于此示例-但出于实际目的,您可以将a:1视为与 :a => 1相同。

您还可以使用Ripper#sexp来检查源代码,以查看解释器将如何解析行。例如:

require 'ripper'

pp Ripper.sexp "{a: 1}"
[:program,
 [[:hash,
   [:assoclist_from_args,
    [[:assoc_new, [:@label, "a:", [1, 1]], [:@int, "1", [1, 4]]]]]]]]
#=> [:program, [[:hash, [:assoclist_from_args, [[:assoc_new, [:@label, "a:", [1, 1]], [:@int, "1", [1, 4]]]]]]]]

pp Ripper.sexp "{:a => 1}"
[:program,
 [[:hash,
   [:assoclist_from_args,
    [[:assoc_new,
      [:symbol_literal, [:symbol, [:@ident, "a", [1, 2]]]],
      [:@int, "1", [1, 7]]]]]]]]
#=> [:program, [[:hash, [:assoclist_from_args, [[:assoc_new, [:symbol_literal, [:symbol, [:@ident, "a", [1, 2]]]], [:@int, "1", [1, 7]]]]]]]]

在这两种情况下,都可以看到S表达式使用冒号来构建“assoc_new”子表达式。如需进一步深入了解,您需要参考Ruby源代码树。

另请参阅


1
:=>符号是Ruby语言的一部分,即方法或对象概念下面的东西。在语言实现中,它们被解析器识别。因此,解析器会查看您的源代码,对其进行解析,并(在本例中)基于源代码创建对象。特定的语法元素导致创建各种对象,例如,如果您在源代码中写入3.14,则会创建一个新的Float对象。同样,由Ruby解析器识别为创建哈希的定义语法定义了各种选项,以描述您源代码中的哈希,例如:
{ :symbol => 'value' }
{ symbol: 'value' }
{ 'symbol': 'value' }

这些选项中的每一个都会创建相同的哈希,即具有符号键和字符串值的哈希。

第一种语法选项是定义哈希的唯一原始语法。其他选项是后来引入的,为开发人员提供更多以更“自然”的方式定义哈希的选项。


谢谢你的回答,Holger。打开“RACC之门”是了解Ruby底层工作原理的好方法! - Sumak

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