如何在Smalltalk中重写相等方法?

如何在Smalltalk中重写相等方法?,smalltalk,gnu-smalltalk,pharo,Smalltalk,Gnu Smalltalk,Pharo,我在读一篇文章,我有一个练习,关于消失元素的异常,我无法解决 Object subclass: Book [ | isbn | <comment: 'A book class'> setIsbn: anIsbn [ isbn := anIsbn. ] getIsbn [ ^isbn. ] = anotherBook [ ^self getIsbn = anotherBook

我在读一篇文章,我有一个练习,关于消失元素的异常,我无法解决

Object subclass: Book [
    | isbn |
    <comment: 'A book class'>

    setIsbn: anIsbn [
        isbn := anIsbn.
    ]

    getIsbn [
        ^isbn.
    ]

    = anotherBook [
        ^self getIsbn = anotherBook getIsbn.
    ]
]

| Library |

Library := Set new: 100.
Library add: (Book new setIsbn: '0-671-2-158-1').
(Library includes: (Book new setIsbn: '0-671-2-158-1')) printNl.
对象子类:Book[
|isbn|
setIsbn:anIsbn[
isbn:=anIsbn。
]
getIsbn[
^isbn。
]
=另一本书[
^self getIsbn=另一本书getIsbn。
]
]
|图书馆|
库:=设置新:100。
图书馆地址:(图书新集ISBN:'0-671-2-158-1')。
(图书馆包括:(图书新集ISBN:'0-671-2-158-1'))印刷NL。

我读到我也必须重写
hash
方法,但我不知道怎么做。如何修改
书籍
类以避免异常?

我真的不知道您在问什么,但要覆盖哈希,您应该像覆盖
=
一样,只需包含不同的定义即可。所以你会做一些类似的事情:

hash [
  "return hash here"
]
如果你想知道散列应该是什么样的,那么不妨这样想:相等的对象必须有相同的散列(但这不必反过来)。所以我建议你做一些类似的事情

hash [
  ^ self getIsbn hash
]
还有关于消失的元素。Set是一个散列集合。这意味着在将它的元素与您要查找的元素进行比较之前,它会通过哈希选择一个子集。因此,如果您不重写哈希,它可能会选择不包含所需元素的子集


最后,我建议您使用一些不同的Smalltalk实现,因为当我开始学习Smalltalk时,我的头很痛。就个人而言,我使用它提供了一个很好的用户界面,允许您查看覆盖的内容,允许您进行调试等。

您的代码还存在一些Smalltalk惯用用法问题:

  • 通常,Smalltalk中的访问器不使用get和set。所以你有
    isbn:anIsbn
    isbn
  • 您可能想创建一个额外的构造函数,将ISBN作为参数,这样您就不必自己发送
    new
    和setter:

    Book>>onIsbn: anIsbn    
    
        ^self new
             isbn: anIsbn;
             yourself
    

    • 基本规则是永远不要覆盖
      =不覆盖
      #hash

      非常感谢,这正是我想要的。当我重写该方法时,我不知道应该散列哪段数据。但现在有了意义。#散列覆盖+1,但我个人会省略最后一段。@Frankshierar是的,你是对的。但我不在乎。用gnu smalltalk编程对我来说真的很痛苦,因为你不知道图像中有什么,你的代码在哪里等等。。。也许我可以用最后一句话来帮助这家伙。(是的,我可以推荐其他smalltalk方言,但我不想推荐一些我不确定的东西)标记识别中的一些错误使得最后一段代码相当不可读