3

我正在读一本关于 Smalltalk的书,我有一个关于我无法解决的消失元素异常的练习。

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.

我读过我也必须重写该hash方法,但我不知道该怎么做。如何修改Book课程以避免异常

4

3 回答 3

7

我真的不知道你在问什么,但要覆盖哈希,你应该做与=你已经覆盖的 with 相同的事情,只是包含不同的定义。所以你做这样的事情:

hash [
  "return hash here"
]

如果您要问哈希应该是什么样的……那么请这样想:相等的对象必须具有相同的哈希(但这不必反过来工作)。所以我建议你做类似的事情

hash [
  ^ self getIsbn hash
]

还有关于消失的元素。Set 是一个散列集合。这意味着在将其元素与您要查找的元素进行比较之前,它会通过哈希选择一个子集。因此,如果您没有覆盖哈希,它可能会选择一个不包含您想要的元素的子集。

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

于 2013-12-31T14:11:18.547 回答
2

您的代码还有一些其他 Smalltalk 惯用问题:

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

    Book>>onIsbn: anIsbn    
    
        ^self new
             isbn: anIsbn;
             yourself
    
于 2014-01-03T11:27:11.717 回答
1

基本规则是 never override #= without overriding#hash

于 2014-02-27T08:28:44.073 回答