查看 HyperSpec中#'adjoin的文档,我在示例部分看到以下内容:
(setq slist '()) => NIL
(setq slist (adjoin '(test-item 1) slist)) => ((TEST-ITEM 1))
(adjoin '(new-test-item 1) slist :key #'cadr) => ((TEST-ITEM 1))
相反,我会期待以下内容:
(adjoin '(new-test-item 1) slist :key #'cadr) => ((NEW-TEST-ITEM 1) (TEST-ITEM 1))
我的期望是由于HyperSpec (17.2.1)中的以下文本:
当下图中列出的运算符 F 对序列 S 的每个元素 Ei 迭代地考虑对象 O 时,有时控制在 S 中测试 O 的存在的方式由 F 测试是有用的。这控制是基于使用 :test 或 :test-not 参数指定的函数提供的。
并进一步:
对象 O 可能不会直接与 Ei 进行比较。如果提供了 :key 参数,则它是一个参数的函数的指示符,该函数以每个 Ei 作为参数调用,并产生一个用于比较的对象 Zi。(如果没有 :key 参数,Zi 就是 Ei。)
:key 参数指定的函数永远不会在 O 本身上调用。但是,如果该函数对多个序列进行操作(例如,在 set-difference 中发生),则 O 将是在另一个序列的元素上调用 :key 函数的结果。
所以我们有 slist (序列,S) as'((TEST-ITEM 1))
和 O as '(new-test-item 1)
。为了检查 O 是否应该相邻,函数#'cadr
应用于 S 的元素,第一个是'(test-item 1)
。因此,该测试给出:
(cadr '(test-item 1)) => 1
现在,当 O, , 与应用于S 的 E1'(new-test-item 1)
的结果进行检查时(当没有提供 时使用的相等函数),结果应该意味着 O 是邻接的。至少我会这么认为。我有什么误解?#'cadr
#'eql
:test
false