我想使用Common Lisp CLOS对象作为散列表中的键。我原以为会这么简单:
(defclass my-class () ((a :accessor a :initarg a)))
(defun my-class= (my-instance-1 my-instance-2)
(equal (a my-instance-1) (a my-instance-2)))
(defparameter my-hash-table (make-hash-table :test #'my-class=))
查看公共Lisp Hyperspec,似乎我只能使用eq, eql, equal或equp来测试相等性。
我有什么办法可以做到吗?或者这只是一件愚蠢的事情,这就是为什么标准不允许这样做?
公共Lisp标准不提供任何机制来为哈希表提供额外的测试函数(超出标准的)。你有两个选项:
- 使用genhash genhash,这是可移植的哈希表实现(与内置的不兼容)
- 使用非标准扩展:
- SBCL具有
sb-ext:define-hash-table-test
功能(文档) - clip有类似的功能
ext:define-hash-table-test
(文档) - Allegro和Lispworks接受
:test
参数的非标准值,并有:hash-function
参数(Allegro, Lispworks)。