我一直在尝试使用以下代码修改哈希表
(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))
答案 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-macrolet
和define-symbol-macro
),但这是相对先进的材料,你现在应该忽略IMO
答案 1 :(得分:1)
为什么要混合关联列表和哈希表?两者都可以用于类似目的,但它们彼此独立。
如果你想把东西放到哈希表中,你必须写:
(setf (gethash key *hash-table*) value)
如果你想获得价值:
(gethash key *hash-table*)