你可以使用任何你想要的值,只要你使用相同的值。
x = "A string value"
h = Hash[ 10000.times.map{|i| [i, x]} ]
h2 = Hash[ 10000.times.map{|i| [i, nil]} ]
# h takes the same memory as h2
在上面的例子中,x 可以是你喜欢的任何东西。如果x 是立即值(nil、true、false 或Fixnum),这些值将只保存指向x 的指针或值本身。
在任何一种情况下,使用的内存都是相同的!它将是您平台上指针的大小(即0.size 字节)。在 C 代码中,这对应于 VALUE。
请注意重复使用相同的对象(即相同的object_id),而不是每次都创建新对象。例如:
h3 = Hash[ 10000.times.map{|i| [i, "A string value"]} ]
# => h3 will take a lot more space!
h.values.map(&:object_id).uniq.size # => 1
h3.values.map(&:object_id).uniq.size # => 10000
简而言之,一个可靠的方法是使用false、true、nil、Fixnum 或Symbol,因为符号存储在全局表中。 :hello.object_id 在任何地方都是相同的,字符串 'hello' 只存储一次,并为代码中的所有 :hello 符号共享。
h4 = Hash[ 10000.times.map{|i| [i, :some_symbol]} ]
# => h4 will only take as much space as h and h2
h4.values.map(&:object_id).uniq.size # => 1
仅供参考,内置库 Set 具有相同的要求,即它仅将 Hash 用于键。为简单起见,它使用true 作为值。