Hash生成对象

#new(默认值)
h = Hash.new("hello world")
h["demo"] # "hello world"

#new{|hash, key|},参数依次是hash值和hash的key
h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
h["c"]           #=> "Go Fish: c"
h["c"].upcase!   #=> "GO FISH: C"
h["d"]           #=> "Go Fish: d"
h.keys           #=> ["c", "d"]

使用对象作为hash的key

Hash keys must respond to the message `hash` by returning a hash code, and the hash code for a given key must not change. The keys used in hashes must also be comparable using `eql?`. If `eql?` returns `true` for two keys, then those keys must also have the same hash code. This means that certain classes (such as `Array` and `Hash`) can’t conveniently be used as keys, because their hash values can change based on their contents. 【programming ruby】

就是说如果要把对象当成是hash的key,那么这个对象必须满足实现两个方法,分别是eql?和hash方法,eql?会进行比较,hash的返回值要相同,那么认为是是相同的key。

#代码示例
class Key
  attr_reader :value

  def initialize(value)
    @value = value
  end

  def eql?(other_key)
    value == other_key.value
  end

  def hash
    value.hash
  end
end

k1 = Key.new('foo')
k2 = Key.new('foo')

h = { k1 => 'bar' }
puts h.has_key? k1 # -> true
puts h.has_key? k2 # -> true

很多场合中一般用alias关键词

def ==(other)
    self.class === other and
      other.author == @author and
      other.title == @title
  end

alias eql? ==

使用hash[:demo]的形式获取hash中的值,但是如果这个hash的key不存在,返回nil,如果hash在生成的过程中定义了块,那么如果没有获取相应的key,会调用块中的内容

#一般情况下没有使用块
h = {}
h[:demo] #nil

#使用块的形式
hash = Hash.new{|hash, key| raise(KeyError, "invalid error #{key}") }
hash[:demo] # invalid error key

results matching ""

    No results matching ""