哈希¶
一个 Hash 是一个通用的键值对集合,将类型为 K
的键映射到类型为 V
的值。
哈希通常使用哈希字面量创建,哈希字面量由花括号 ({ }
) 括起来,其中包含使用 =>
作为键和值之间分隔符且用逗号 ,
分隔的键值对列表。
{"one" => 1, "two" => 2}
泛型类型参数¶
键 K
和值 V
的泛型类型参数分别从字面量中键或值的类型推断得出。当所有类型都相同时,K
/V
等于该类型。否则,它将分别为所有键类型或值类型的并集。
{1 => 2, 3 => 4} # Hash(Int32, Int32)
{1 => 2, 'a' => 3} # Hash(Int32 | Char, Int32)
可以通过在右括号后紧跟 of
(用空格分隔)、键类型 (K
) 后跟 =>
作为分隔符以及值类型 (V
) 来指定显式类型。这会覆盖推断出的类型,例如,可以用来创建一个最初只包含某些类型的哈希,但也可以接受其他类型的哈希。
空哈希字面量始终需要类型规范
{} of Int32 => Int32 # => Hash(Int32, Int32).new
类哈希类型字面量¶
Crystal 支持哈希和类哈希类型的附加字面量。它由类型的名称后跟花括号 ({}
) 括起来的逗号分隔的键值对列表组成。
Hash{"one" => 1, "two" => 2}
只要类型具有无参数构造函数并响应 []=
,就可以使用此字面量。
HTTP::Headers{"foo" => "bar"}
对于像 HTTP::Headers
这样的非泛型类型,这等效于
headers = HTTP::Headers.new
headers["foo"] = "bar"
对于泛型类型,泛型类型会像哈希字面量一样从键和值的类型推断得出。
MyHash{"foo" => 1, "bar" => "baz"}
如果 MyHash
是泛型,上面的代码等效于
my_hash = MyHash(typeof("foo", "bar"), typeof(1, "baz")).new
my_hash["foo"] = 1
my_hash["bar"] = "baz"
类型参数可以作为类型名称的一部分显式指定
MyHash(String, String | Int32){"foo" => "bar"}