【问题标题】:Modifying hash-tables in Common Lisp and Let在 Common Lisp 和 Let 中修改哈希表
【发布时间】:2014-10-06 02:16:30
【问题描述】:

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

(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)))

我不明白为什么这个有效而另一个无效。这很有用(在这段代码 sn-p 之外),因为(我假设)这就是为什么我不能运行像

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

定义为:

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

【问题讨论】:

    标签: lisp hashtable common-lisp evaluation


    【解决方案1】:

    设置变量会修改其本地绑定。 你没想到

    (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 绑定到返回的值。然后setf修改了alist的绑定,完全忽略了之前的绑定。

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

    你的函数应该这样定义:

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

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

    “为了全面披露”,CL 确实提供了您想要的设施(请参阅 symbol-macroletdefine-symbol-macro),但这是相对先进的材料,IMO,您现在应该忽略它。

    【讨论】:

      【解决方案2】:

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

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

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

      如果要获取值:

      (gethash key *hash-table*)
      

      【讨论】:

        猜你喜欢
        • 2010-10-07
        • 2015-06-04
        • 1970-01-01
        • 1970-01-01
        • 2011-08-19
        • 1970-01-01
        • 2019-04-21
        • 1970-01-01
        • 2015-08-27
        相关资源
        最近更新 更多