Lisp:在宏中扩展 属性 名称
Lisp: expand property name in macro
考虑这个 属性 列表:
(defvar *some-variable* (list :foo "fooval" :bar "barval"))
这个简单的调用:
(getf *some-variable* :foo)
产量 "fooval"
如预期。我定义了一个宏,它应该做同样的事情,除了我可以传递任何 属性 的名称来检索:
(defmacro my-macro (property-name)
`(getf *some-variable* :,property-name))
不幸的是,这样称呼它:
(my-macro 'foo)
结果 FOO
。为什么?
你为什么不自己检查一下:
(macroexpand-1 '(my-macro 'foo))
; ==> (getf *some-variable* :|| 'foo) ;
T
documentation for getf
表示如果给它第 4 个参数,它就是找不到键时的值。由于 :||
(关键字包中的空符号)不存在 returns 提供的默认值 foo
。
所以这里有一个函数可以满足您的需求:
(defun get-field (name)
(getf *some-variable*
(intern (symbol-name name) "KEYWORD")))
(defparameter *test* 'foo)
(get-field *test*)
; ==> "fooval"
使它成为宏的唯一原因是使它成为语法,而语法和函数之间的主要区别在于不评估参数。
(defmacro get-mfield (name)
`(get-field ',name))
(get-mfield foo)
; ==> "fooval"
(get-mfield *test*)
; ==> nil
你可以直接使用文字,但是你失去了 *test*
被视为变量而不是键 :*test*
的特性
考虑这个 属性 列表:
(defvar *some-variable* (list :foo "fooval" :bar "barval"))
这个简单的调用:
(getf *some-variable* :foo)
产量 "fooval"
如预期。我定义了一个宏,它应该做同样的事情,除了我可以传递任何 属性 的名称来检索:
(defmacro my-macro (property-name)
`(getf *some-variable* :,property-name))
不幸的是,这样称呼它:
(my-macro 'foo)
结果 FOO
。为什么?
你为什么不自己检查一下:
(macroexpand-1 '(my-macro 'foo))
; ==> (getf *some-variable* :|| 'foo) ;
T
documentation for getf
表示如果给它第 4 个参数,它就是找不到键时的值。由于 :||
(关键字包中的空符号)不存在 returns 提供的默认值 foo
。
所以这里有一个函数可以满足您的需求:
(defun get-field (name)
(getf *some-variable*
(intern (symbol-name name) "KEYWORD")))
(defparameter *test* 'foo)
(get-field *test*)
; ==> "fooval"
使它成为宏的唯一原因是使它成为语法,而语法和函数之间的主要区别在于不评估参数。
(defmacro get-mfield (name)
`(get-field ',name))
(get-mfield foo)
; ==> "fooval"
(get-mfield *test*)
; ==> nil
你可以直接使用文字,但是你失去了 *test*
被视为变量而不是键 :*test*