Crystal 中的 Hash 和 NamedTuple 有什么区别?
What's the difference between Hash and NamedTuple in Crystal?
这两种语法看起来相当相似,它们的用例也很相似。示例:
# Hash
hash = {"name" => "Crystal", "year" => 2011}
hash["name"] # outputs: Crystal
# NamedTuple
tuple = {name: "Crystal", year: 2011}
tuple[:name] # outputs: Crystal
那么这两个原语到底有什么不同呢?
API 文档已经很好地解释了这一点。来自NamedTuple
(我强调):
A named tuple is a fixed-size, immutable, stack-allocated mapping of a fixed set of keys to values.
You can think of a NamedTuple as an immutable Hash whose keys (which are of type Symbol), and the types for each key, are known at compile time.
还有:
The compiler knows what types are in each key, so when indexing a named tuple with a symbol literal the compiler will return the value for that key and with the expected type. Indexing with a symbol literal for which there's no key will give a compile-time error.
相比之下,Hash
:
A Hash is a generic collection of key-value pairs mapping keys of type K to values of type V.
简而言之,散列是一种可以在运行时更改的数据结构,所有 keys/values 都可以具有任何类型,只要它与通用类型参数 K/V 匹配即可。
另一方面,命名元组是一种不可变的数据结构,在编译时是完全已知的。如果您访问一个键,编译器就会知道它的类型。拥有一个命名元组非常类似于将键作为具有公共前缀的变量:
foo = {bar: "bar", baz: 1}
foo_bar = "bar"
foo_baz = 1
NamedTuple
只是添加了一些工具来将这些变量用作一个连贯的集合。
这两种语法看起来相当相似,它们的用例也很相似。示例:
# Hash
hash = {"name" => "Crystal", "year" => 2011}
hash["name"] # outputs: Crystal
# NamedTuple
tuple = {name: "Crystal", year: 2011}
tuple[:name] # outputs: Crystal
那么这两个原语到底有什么不同呢?
API 文档已经很好地解释了这一点。来自NamedTuple
(我强调):
A named tuple is a fixed-size, immutable, stack-allocated mapping of a fixed set of keys to values.
You can think of a NamedTuple as an immutable Hash whose keys (which are of type Symbol), and the types for each key, are known at compile time.
还有:
The compiler knows what types are in each key, so when indexing a named tuple with a symbol literal the compiler will return the value for that key and with the expected type. Indexing with a symbol literal for which there's no key will give a compile-time error.
相比之下,Hash
:
A Hash is a generic collection of key-value pairs mapping keys of type K to values of type V.
简而言之,散列是一种可以在运行时更改的数据结构,所有 keys/values 都可以具有任何类型,只要它与通用类型参数 K/V 匹配即可。 另一方面,命名元组是一种不可变的数据结构,在编译时是完全已知的。如果您访问一个键,编译器就会知道它的类型。拥有一个命名元组非常类似于将键作为具有公共前缀的变量:
foo = {bar: "bar", baz: 1}
foo_bar = "bar"
foo_baz = 1
NamedTuple
只是添加了一些工具来将这些变量用作一个连贯的集合。