我有一个结构蜘蛛:
(defstruct spider omegas values k)
和实例蜘蛛:
(set '*spider* (make-spider
:omegas '()
:values (list *input*)
:k '(#'omegashift #'dec #'dupval '((0 . #'dec) (1 . #'inc) (2 . #'dec)))))
但是当我在Emacs和SBCL上运行表达式:(listp (car (spider-k *spider*))
时(涉及SLIME,但我不确定它是什么。)REPL返回T
。显然这令人困惑,因为(car (spider-k *spider*)
正确返回#'OMEGASHIFT
,(listp (function OMEGASHIFT))
正确返回NIL
。
为什么(listp (car (spider-k *spider*))
为真?不应该是假的吗?
#'omegashift
是一个阅读器宏,它扩展到列表(function omegashift)
。
[当您评估(function omegashift)
时,您会得到一个函数,但您没有对它进行评估,因为您引用了该列表。这样您就可以得到阅读器宏扩展到的列表。
如果您进行了(listp (car '('foo)))
,您将看到相同的内容。 'foo
扩展到列表(quote foo)
。其计算结果为符号foo
,但列表前的引用阻止了计算。
要获取函数而不是列表,您需要评估函数表达式。您可以通过调用函数list
而不是引用列表来完成此操作。
(setq *spider* (make-spider
:omegas '()
:values (list *input*)
:k (list #'omegashift #'dec #'dupval (list (cons 0 #'dec) (cons 1 #'inc) (cons 2 #'dec)))))
您还可以使用反引号简化此操作:
(setq *spider* (make-spider
:omegas '()
:values (list *input*)
:k `(,#'omegashift ,#'dec ,#'dupval '((0 . ,#'dec) (1 . ,#'inc) (2 . ,#'dec)))))
在反引号内,您使用逗号标记要评估的子表达式。
顺便说一句,您应该使用setq
分配变量,而不是带引号的set
。它们等效于全局变量,但是不能将set
与局部变量一起使用。