lisp - 在 Common Lisp 和 Let 中修改哈希表

标签 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))

最佳答案

设置变量会修改其本地绑定(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-macroletdefine-symbol-macro),但这是相对高级的 Material ,IMO,您现在应该忽略它。

关于lisp - 在 Common Lisp 和 Let 中修改哈希表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26209250/

相关文章:

sockets - Lisp : Is there a callback that informs that a connection from open-socket has just dropped?

clojure - 使用 clojure.data.xml 从 Clojure 发出 XML。

loops - 如何在 lisp 中生成一个笛卡尔积?

list - 我如何找到一个列表有多少个不同的元素?口齿不清

c# - MethodBase 作为哈希表键

lisp - 在 Lisp 中将数字从某个基数转换为基数 10

Haskell - 类似 Lisp 的符号功能

java - 我需要实现一个数组哈希表,该表无需在开始时将数组初始化为 null 即可工作。任何线索如何做到这一点?

python - 设置弹出(Python)

lisp - 在 lisp 中调用 flat 或 labels 函数