常见的lisp(多个)值是真还是假?

Bla*_*adt 3 common-lisp

我似乎在这里有一个cat-in-a-box类问题以下代码应该,给定一个键和一个哈希表,返回对应于该键的值,如果该键不存在于映射中则为错误:

(defun get-graph-node (key graph)
  (let ((result (gethash key graph)))
    (if (nth-value 1 result)
      (nth-value 0 result)
      (error "no node matches the key"))))
Run Code Online (Sandbox Code Playgroud)

在大多数情况下它确实如此,但我有这种奇怪的情况:

(gethash 0 *g*)
Run Code Online (Sandbox Code Playgroud)

回报

   #S(GRAPH-NODE$
      :DATA "("$
      :EDGES (#S(GRAPH-NODE :DATA "b" :EDGES NIL)$
              #S(GRAPH-NODE :DATA "a" :EDGES NIL)))
   T
Run Code Online (Sandbox Code Playgroud)

(get-graph-node 0 *g*)
Run Code Online (Sandbox Code Playgroud)

表示get-graph-node中定义的错误

检查*g*给我这个:

Count: 5
Size: 16
Test: EQL
Rehash size: 1.5
Rehash threshold: 1.0
[clear hashtable]
Contents: 
0 = #S(GRAPH-NODE :DATA "(" :EDGES (#S(GRAPH-NODE :DATA "b" :EDGES NIL) #S(GRAPH-NODE :DATA "a" :EDGES NIL))) 
[remove entry]
1 = #S(GRAPH-NODE :DATA "a" :EDGES NIL) [remove entry]
2 = #S(GRAPH-NODE :DATA "|" :EDGES (#S(GRAPH-NODE :DATA ")" :EDGES (NIL)))) [remove entry]
3 = #S(GRAPH-NODE :DATA "b" :EDGES NIL) [remove entry]
4 = #S(GRAPH-NODE :DATA ")" :EDGES (NIL)) [remove entry]
Run Code Online (Sandbox Code Playgroud)

所以键0应该在地图中?对我可以告诉我自己缺少什么的绅士来说,这是我的一个巨大的秘密.

jla*_*ahd 6

将gethash的结果赋给变量result时,只存储函数返回的多个值中的第一个.要存储它们,你应该做这样的事情:

(defun get-graph-node (key graph)
  (multiple-value-bind (result exists)
      (gethash key graph)
    (if exists
      result
      (error "no node matches the key"))))
Run Code Online (Sandbox Code Playgroud)

  • @ruakh:除非我遗漏了某些东西,否则`(nth-value 1 result)`将始终为原始代码中的`nil`.`result`总是仅计算一个值. (2认同)