修改Common Lisp和Let中的哈希表

时间:2014-10-06 02:16:31

标签: lisp hashtable common-lisp evaluation

我一直在尝试使用以下代码修改哈希表

(let ((alist '(gethash key *hash-table*)))
  (setf alist (cons 'key 'weight)))

但问题是它实际上并没有修改哈希表(还要注意

(let ((alist (gethash key *hash-table*)))
  (setf alist (cons 'key 'weight)))

也不起作用,而以下代码确实有效。

(setf (gethash key *hash-table*) (cons 'key 'weight)))

我无法理解为什么这会起作用而另一个不起作用。这很有用(在此代码片段之外),因为(我假设)这就是为什么我无法运行像

这样的函数
(alist-initialize (gethash key *hash-table*))

定义为:

(defun alist-initialize (alist)
  (setf alist (cons 'a 'b))

2 个答案:

答案 0 :(得分:9)

设置变量会修改其本地绑定。 你不会指望

(let ((a 5))
  (setf a 2))

以某种方式将5的值更改为2。 同样,

(let ((alist (gethash key *hash-table*))) 
  (setf alist (cons 'key 'weight)))

(gethash key *hash-table*)没有影响。 会发生什么key*hash-table*中查找,alist与返回的值绑定。然后setf修改了alist的绑定,完全忘记了以前的绑定。

(请注意,您的第一个表单引用了[gethash][2]调用,因此根本不会访问哈希表。

您的功能应该像这样定义:

(defun alist-initialize (key alist)
  (setf (gethash key *hash-table*) alist))

并使用两个参数调用,而不是一个

“为了充分披露”,CL确实提供了你想要的设施(见symbol-macroletdefine-symbol-macro),但这是相对先进的材料,你现在应该忽略IMO

答案 1 :(得分:1)

为什么要混合关联列表和哈希表?两者都可以用于类似目的,但它们彼此独立。

如果你想把东西放到哈希表中,你必须写:

(setf (gethash key *hash-table*) value)

如果你想获得价值:

(gethash key *hash-table*)