list - Lisp 的 getf 如何处理列表?

标签 list lisp common-lisp

所以我有一段简单的代码:

(defun lol (z) (getf (list :a 1 :b 2 :c 3) :z))

当我启动函数时:

(lol '(a))

它只是给了我 NIL 而不是 1。从技术上讲,上面的内容不等于:

(getf (list :a 1 :b 2 :c 3) :a)

为什么会发生这种情况,我该如何解决?

最佳答案

还有一些其他答案涵盖了这个问题,但我认为有时举个例子很有用。重要的是符号有,并且(除了一些注意事项)在一个包中具有给定名称的符号与在另一个包中具有相同名称的符号是不同的符号。 p>

CL-USER> (defparameter *plist* (list 'a 1 ':a 2))
*PLIST*
CL-USER> (first *plist*)
A
CL-USER> (third *plist*)
:A
CL-USER> (eql (first *plist*) (third *plist*))
NIL
CL-USER> (getf *plist* 'a)
1
CL-USER> (getf *plist* ':a)
2

现在,一开始可能会让人有点困惑的是符号的打印方式并不总是显示符号的完整包名。上面提示中的“CL-USER”表示当前包是 CL-USER 包,因此该包中的符号或该包使用的符号不会与其包名一起显示。如果我们创建一个新包并切换到它,并打印 *plist*,我们可以看到:

CL-USER> (defpackage #:temp)
#<PACKAGE "TEMP">
CL-USER> (in-package #:temp)
#<COMMON-LISP:PACKAGE "TEMP">
TEMP> cl-user::*plist*
(COMMON-LISP-USER::A 1 :A 2)

请注意,*plist* 的第一个元素打印有“COMMON-LISP-USER”(“CL-USER”是“COMMON-LISP-USER”的昵称)。现在,符号 :A 以相同的方式打印。这是怎么回事? Common Lisp 有一个特殊的包,称为“KEYWORD”,该包中的符号称为关键字符号。它们与其他符号非常相似,只是它们都绑定(bind)到自己(因此评估 :a 会产生 :a,并且不需要引用),它们都是外部的,通常以单个冒号作为前缀打印。不过,如果您愿意,您可以编写关键字前缀:

TEMP> 'keyword::a
:A
TEMP> 'keyword:b
:B
TEMP> keyword::c  ; no need to quote
:C
TEMP> keyword:d
:D

所以,如果你想写一个函数,它接受一个属性列表指示器并为它检索某个固定属性列表中的值,你会做这样的事情(注意属性列表中的指示器没有成为符号,如最后一个示例所示):

(defun example (indicator)
  (getf '(:a 1 :b 2 c 3 4 5) indicator))

CL-USER> (example :a)        ; OR ':a OR keyword::A OR ...
1
CL-USER> (example keyword:b) ; OR ...
2
CL-USER> (example 'c)        ; OR 'cl-user::c OR ...
3
CL-USER> (example 4)         ; OR (+ 2 2) OR ...
5

关于list - Lisp 的 getf 如何处理列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33382993/

相关文章:

scheme - 评估组合以递归处理 (+ 1 2)

clojure - 我如何从clojure中给定的两个值一个一个地调用一个函数

r - 从列表值创建数据框

list - 从 Erlang 中的不正确列表返回第一个元素

java - List 中基于另一个元素的最大值

scheme - 递归序列的 Racket 条件和

c - 如何释放c中双向链表程序的内存

LISP编程

LISP 修改列表作为参数传递

lisp - 剪辑 : remove from list of list