代码之家  ›  专栏  ›  技术社区  ›  mxcl

Ruby的数组如何。比较元素是否相等?

  •  5
  • mxcl  · 技术社区  · 15 年前

    下面是一些示例代码:

    class Obj
      attr :c, true
    
      def == that
        p '=='
        that.c == self.c
      end
      def <=> that
        p '<=>'
        that.c <=> self.c
      end
      def equal? that
        p 'equal?'
        that.c.equal? self.c
      end
      def eql? that
        p 'eql?'
        that.c.eql? self.c
      end
    end
    
    a = Obj.new
    b = Obj.new
    
    a.c = 1
    b.c = 1
    
    p [a] | [b]
    

    它打印2个对象,但应该打印1个对象。没有调用任何比较方法。数组如何。比较是否相等?

    3 回复  |  直到 15 年前
        1
  •  6
  •   sepp2k    15 年前

    Array#| 使用哈希实现。因此,为了使您的类型能够很好地使用它(以及使用散列映射和散列集),您必须实现 eql? (你做的)和 hash (你没有)。最直接有意义地定义哈希的方法是返回 c.hash .

        2
  •  1
  •   igul222    15 年前

    Ruby的数组类是在C中实现的,据我所知,在比较 | . 如果你想修改这个行为,你就必须编写自己的版本,使用你选择的相等性检查。

    查看Ruby的完整实现 Array#| 以下内容: click here 并搜索“ rb_ary_or(VALUE ary1, VALUE ary2)

        3
  •  0
  •   DigitalRoss    15 年前

    Ruby正在调用散列函数,它们返回不同的值,因为它们仍然只是返回默认对象\u id。 def hash 并且返回一些反映你对什么使obj有意义的想法的东西。

    >> class Obj2 < Obj
    >>   def hash; t = super; p ['hash: ', t]; t; end
    >> end
    => nil
    >> x, y, x.c, y.c = Obj2.new, Obj2.new, 1, 1
    => [#<Obj2:0x100302568 @c=1>, #<Obj2:0x100302540 @c=1>, 1, 1]
    >> p [x] | [y]
    ["hash: ", 2149061300]
    ["hash: ", 2149061280]
    ["hash: ", 2149061300]
    ["hash: ", 2149061280]
    [#<Obj2:0x100302568 @c=1>, #<Obj2:0x100302540 @c=1>]