加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

common-lisp – 使用CLOS类实例作为哈希表键?

发布时间:2020-12-15 03:16:16 所属栏目:Java 来源:网络整理
导读:我有以下课程: (defclass category () ((cat-channel-name :accessor cat-channel-name :initarg :cat-channel-name :initform "" :type string :documentation "Name of the channel of this category") (cat-min :accessor cat-min :initarg :min :initfo
我有以下课程:
(defclass category ()
    ((cat-channel-name
    :accessor cat-channel-name :initarg :cat-channel-name :initform "" :type string
    :documentation "Name of the channel of this category")
    (cat-min
    :accessor cat-min :initarg :min :initform 0 :type number
    :documentation "Mininum value of category")
    (cat-max
    :accessor cat-max :initarg :max :initform 1 :type number
    :documentation "Maximum value of category"))
    (:documentation "A category"))

现在,我想将此类用作哈希表的键.实例的地址可以很容易地与eq进行比较.但问题是,这个类别类可能有多个相同的实例,我希望哈希表也将其识别为一个键.

所以,我试图覆盖make-hash-table函数的:test参数,如下所示:

(make-hash-table :test #'(lambda (a b) (and (equal (cat-channel-name a) (cat-channel-name b))
                                            (eq (cat-min a) (cat-min b))
                                            (eq (cat-max a) (cat-max b)))

不幸的是,这是不允许的. :test需要成为eq,eql,equal或equalp函数之一的指示符.

解决这个问题的一种方法是将类类别转换为结构类,但我需要将它作为一个类.有什么办法可以解决这个问题吗?

解决方法

您可以使用更可扩展的哈希表库,如coredump的答案中所述,但您也可以使用Common Lisp对符号采用的方法:您可以实习它们.在这种情况下,您只需要一个适当的实习函数,该函数需要足够的类别来生成规范实例,并使用哈希表来存储它们.例如,具有简化的类别类别:
(defclass category ()
  ((name :accessor cat-name :initarg :name)
   (number :accessor cat-number :initarg :number)))

(defparameter *categories*
  (make-hash-table :test 'equalp))

(defun intern-category (name number)
  (let ((key (list name number)))
    (multiple-value-bind (category presentp)
        (gethash key *categories*)
      (if presentp category
          (setf (gethash key *categories*)
                (make-instance 'category
                               :name name
                               :number number))))))

然后,您可以使用相同的参数调用intern-category并返回相同的对象,您可以安全地将其用作哈希表键:

(eq (intern-category "foo" 45)
    (intern-category "foo" 45))
;=> T

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读