【问题标题】:What are => and : in Ruby?Ruby 中的 => 和 : 是什么?
【发布时间】:2020-09-17 10:00:18
【问题描述】:

当我们在 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" }

来自this question,mu is too short 的精彩回答说:

JavaScript 样式 (key: value) 仅在您的所有哈希键都是“简单”符号(或多或少与 /\A[a-z_]\w*\z/i 匹配的符号)时才有用 [...] 但是,如果您的密钥不是符号,您仍然需要 hashrocket。

这让我将:=> 视为方法(但我知道我错了)。但是,我在文档中找不到任何关于它的内容。

:=> 究竟是什么?我怎样才能了解更多关于它们的信息,以及它们在 Ruby 的源代码中定义在哪里?

【问题讨论】:

标签: ruby hash


【解决方案1】:

词法分析器/解析器标记

您引用的符号不是方法或运算符,它们是用于解释源代码语法的词法分析器/解析器标记。 hashrocket 定义为tASSOC association token,用于关联键/值对或exception stack traces等事物。

冒号在 Ruby 中有多种用途,但当左侧是符号时,IIRC Ruby 2.x 引入了后缀冒号作为 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 源代码树。

另见

【讨论】:

    【解决方案2】:

    :=> 符号是 Ruby 语言语法的一部分,即在方法或对象的概念级别之下。

    在语言实现中,它们被解析器识别。因此,解析器会看到您的源代码,对其进行解析并(在这种情况下)基于源代码创建对象。特定的语法元素会导致创建各种对象,例如如果您在源代码中写入3.14,则会创建一个新的Float 对象。同样,Ruby 解析器识别的用于创建哈希的定义语法定义了在源代码中描述哈希的各种选项,例如

    { :symbol => 'value' }
    { symbol: 'value' }
    { 'symbol': 'value' }
    

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

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

    【讨论】:

    • 感谢您的回答 Holger,打开“RACC 的门”是第一次了解 Ruby 如何在引擎盖下工作!
    猜你喜欢
    • 1970-01-01
    • 2012-06-15
    • 1970-01-01
    • 2010-09-14
    • 1970-01-01
    • 1970-01-01
    • 2016-09-17
    • 2013-01-31
    • 2010-10-29
    相关资源
    最近更新 更多