我一直在尝试使用以下代码修改哈希表
(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))
最佳答案
设置变量会修改其本地绑定(bind)。 你不会想到
(let ((a 5))
(setf a 2))
以某种方式将 5
的值更改为 2
。
同样,
(let ((alist (gethash key *hash-table*)))
(setf alist (cons 'key 'weight)))
对 (gethash key *hash-table*)
没有影响。
发生的事情是它在 *hash-table*
和 alist
中查找的 key
绑定(bind)到返回的值。那么setf
修改 alist
的绑定(bind),完全忽略之前的绑定(bind)。
(请注意,您的第一个表单引用了 gethash
调用,因此根本不访问哈希表)。
你的函数应该这样定义:
(defun alist-initialize (key alist)
(setf (gethash key *hash-table*) alist))
并使用两个参数调用,而不是一个。
“为了全面披露”,CL 确实提供了实现您想要的功能的工具(请参阅 symbol-macrolet
和 define-symbol-macro
),但这是相对高级的 Material ,IMO,您现在应该忽略它。
关于lisp - 在 Common Lisp 和 Let 中修改哈希表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26209250/