对使用符号符号到达 Ruby Hash 内部的百万种方法感到困惑

wha*_*les 5 ruby hash

我沉迷于访问哈希的百万种方式。

condition1 = {
    "e" =>1
}

condition2 = {
    "e":1
}

condition3 = {
    :"e" =>3
}


condition4 = {
    e:4
}


condition5 = {  # 100% sure not working because of syntax error
    e=>5
}

condition6 = {  # 100% sure not working because of syntax error
    :e:6
}  

condition7 = {
    :e=>7
}

puts condition1["e"]
puts condition2["e"]
puts condition3[:e]
puts condition4[:e]
puts condition7[:e]
Run Code Online (Sandbox Code Playgroud)

输出

1
                                     (nothing)
3
4
7
Run Code Online (Sandbox Code Playgroud)

第一个问题:对于第一个 2 puts 语句,为什么它适用于第一个而不适用于第二个?在两个哈希中,我都使用字符串作为键。是不是因为我在第一个哈希中使用了“=>”,因此字符串实际上被读取为符号?所以它实际上被处理为:“e”=>1?

第二个问题:这引出了我关于第三个条件的第二个问题,有人告诉我,如果我在引用之前使用符号符号,那么在后台发生的情况是引用将被忽略。这就是为什么我能够通过简单的 :e 访问它而不带引号。真的吗?然而,如果这是真的,那么第一个问题就会变得更加混乱。如果在第一个条件下,“e”=>1 被评估为:“e”=>1,那么引号不应该被忽略吗?因此最终它被读作 :e =>1。那我怎么只用引号就可以访问它呢?

第三个问题:那么我如何访问第二个条件?我知道不建议使用字符串作为键值。但是,如果在某些情况下我已经用字符串创建了它,我该如何访问它呢?我尝试通过变量名访问它,但它仍然没有输出任何内容。

非常感谢您阅读本文。我知道过分关心这些细节绝对不值得。但是我今天遇到了它,如果不弄清楚到底发生了什么,就无法真正继续前进!!

Jor*_*ing 7

经验法则

如果有冒号 ( :),则它是一个符号。如果有 hashrocket ( =>),则它是 hashrocket 左侧的任何东西(可以是任何东西)。

在哈希文字中声明键

当我们说“哈希文字”时,我们指的是用花括号 ( { foo: 1 }) 或方法参数 ( bar(baz: 2)) 声明哈希的代码。

有两种方法可以在 Hash 文字中声明键。

带有 hashrockets 的键 ( =>)

声明密钥的第一种方法是使用 hashrocket ( =>)。当你使用 hashrocket 时,键是它左边的任何值,你可以把任何类型的对象(或表达式)放在它的左边:

hashrocket_hash = {
  "I am a String" => 1,
  :I_am_a_Symbol => 2,
  :"I am also a Symbol" => 4,
  /I am a Regexp!/ => 5,
  Kernel => 6,
  if true then "I am also a String" end => 7,
  nil => 8
}

p hashrocket_hash.keys
# => [ "I am a String",
#      :I_am_a_Symbol,
#      :"I am also a Symbol",
#      /I am a Regexp!/,
#      Kernel,
#      "I am also a String",
#      nil
#    ]

p hashrocket_keys.map(&:class)
# => [ String,
#      Symbol,
#      Symbol,
#      Regexp,
#      Module,
#      String,
#      NilClass
#    ]
Run Code Online (Sandbox Code Playgroud)

带冒号 ( :) 的键

声明键的另一种方法是使用冒号 ( :)。当您使用冒号时,结果键始终是一个符号。通常的符号规则适用(阅读这里非常彻底的答案:ruby 符号(语法)包含什么?)除了冒号出现在末尾而不是开头:

colon_hash = {
  I_am_a_Symbol: 9,
  "I am also a Symbol": 10
}

p colon_hash.keys
# => [ :I_am_a_Symbol,
#      :"I am also a Symbol" ]

p colon_hash.keys.map(&:class)
# => [ Symbol,
#      Symbol ]
Run Code Online (Sandbox Code Playgroud)

访问哈希值

访问哈希值没有特殊规则。如果要访问键为 Symbol 的值,则必须使用 Symbol。如果要访问键为字符串的值,则必须使用字符串。如果钥匙是别的东西,你必须使用那个东西。

在下面的示例中,请密切注意哪些键后跟冒号,哪些后跟 hashrockets:

hsh1 = { foo: 1 }
p hsh1[:foo]   # => 1
p hsh1[:"foo"] # => 1
p hsh1["foo"]  # => nil

hsh2 = { "bar": 2 }
p hsh2[:bar]   # => 2
p hsh2[:"bar"] # => 2
p hsh2["bar"]  # => nil

hsh3 = {
  Kernel: 3,
  Kernel => 4
}
p hsh3[:Kernel]  # => 3
p hsh3[Kernel]   # => 4
p hsh3["Kernel"] # => nil
Run Code Online (Sandbox Code Playgroud)