Common Lisp中如何正确遍历符号作为哈希表键 解决gethash返回nil问题
问题根源
你在定义*nodes*和*edges*时错误使用了两层引用,外层quote已经会阻止整个列表的求值,内层额外加的单引号会导致列表中的元素不是城市符号本身,而是(quote 城市名)的引用表达式。比如'('Paris)实际等价于(quote ( (quote Paris) )),因此你遍历*nodes*拿到的每个node是带quote的表达式(打印时显示为'PARIS),而不是符号PARIS本身。哈希表的键判定是基于对象相等性的,你后续用'PARIS(求值得到符号PARIS)去查对应键自然返回nil,手动添加的键是符号PARIS,所以会和之前的带引用表达式同时出现在哈希表的键列表中。
修复方案
只需要去掉*nodes*和*edges*定义中的内层单引号即可,外层quote已经保证列表内的符号不会被求值,直接作为符号对象存储:
修复后代码
;; 去掉列表内层的所有单引号 (defvar *nodes* '(San-Francisco Chicago Atlanta Washington Montreal New-York Madrid Paris London Essen Milan St-Petersburg)) (defvar *edges* '((Chicago St-Petersburg) (San-Francisco Atlanta Montreal) (Chicago Washington) (Atlanta Montreal New-York) (Chicago Washington New-York) (Montreal Washington Madrid London) (New-York London Paris) (Madrid Essen London Milan) (Madrid Essen London New-York) (London Paris Milan St-Petersburg) (Paris Essen) (Essen Chicago))) (defvar *pandemic-node-hash* (make-hash-table)) ;; 原有循环无需修改 (loop for node in *nodes* for edges in *edges* do (setf (gethash node *pandemic-node-hash*) edges))
修复后执行(gethash 'PARIS *pandemic-node-hash*)就能正常返回巴黎对应的边列表。
内容的提问来源于stack exchange,提问作者Halbert
相关产品推荐
相关产品推荐

