Охрененные hash table в Common Lisp
2013.12.20
А вы знали, что в качестве ключа хэш-таблицы в Common Lisp можно использовать любые объекты?
Например, так:
(defparameter *table* (make-hash-table :test #'equal))
; voila: lists
(setf (gethash '(abcde 12345) *table*) 2)
(defclass point ()
((x :initarg x) (y :initarg y)))
;voila: objects (!!)
(setf (gethash (make-instance 'point 'x 1 'y 2) *table*) 44)
После этого делаем:
(loop for key being each hash-key of *table* using (hash-value value)
doing (format T "~a: ~a~%" key value))
Результат:
(ABCDE 12345): 2
#<POINT #x302000EEB56D>: 44
NIL
Однако, следует учесть, что хотя перечисление элементов и работает на объектах, gethash
не найдёт нам элемент по ключу-объекту:
(gethash '(abcde 12345) *table*) => 2 T
(gethash (make-instance 'point 'x 1 'y 2) *table*) => NIL NIL
Так что любой элемент данных, который матчится в самом общем случае по equalp
, может теоретически быть использован как ключ в хэш-таблице. По-моему, это просто офигительно.