use*_*577 2 lisp evaluation hashtable common-lisp
我一直在尝试使用以下代码修改哈希表
(let ((alist '(gethash key *hash-table*)))
(setf alist (cons 'key 'weight)))
Run Code Online (Sandbox Code Playgroud)
但问题是它实际上并没有修改哈希表(也请注意
(let ((alist (gethash key *hash-table*)))
(setf alist (cons 'key 'weight)))
Run Code Online (Sandbox Code Playgroud)
也不起作用,而以下代码确实有效.
(setf (gethash key *hash-table*) (cons 'key 'weight)))
Run Code Online (Sandbox Code Playgroud)
我无法理解为什么这个有效而另一个无效.这很有用(在此代码片段之外)因为(我假设)这就是为什么我不能运行像这样的函数
(alist-initialize (gethash key *hash-table*))
Run Code Online (Sandbox Code Playgroud)
定义是:
(defun alist-initialize (alist)
(setf alist (cons 'a 'b))
Run Code Online (Sandbox Code Playgroud)
设置变量会修改其本地绑定.你不会想到的
(let ((a 5))
(setf a 2))
Run Code Online (Sandbox Code Playgroud)
以某种方式改变的价值5来2.同样的,
(let ((alist (gethash key *hash-table*)))
(setf alist (cons 'key 'weight)))
Run Code Online (Sandbox Code Playgroud)
对...没有影响(gethash key *hash-table*).key它会发生什么,它会查找*hash-table*并alist返回返回的值.然后setf修改绑定alist,完全忘记先前的绑定.
(请注意,您的第一个表单引用了[gethash][2]调用,因此根本不访问哈希表).
你的函数应该像这样定义:
(defun alist-initialize (key alist)
(setf (gethash key *hash-table*) alist))
Run Code Online (Sandbox Code Playgroud)
用两个参数调用,而不是一个.
"为了充分披露",CL确实提供了你想要的设施(见symbol-macrolet和define-symbol-macro),但这是相对先进的材料,你现在应该忽略IMO.