如何在let构造之前或之内检查变量是否已定义?
(let (((if (boundp 'a)
'a
'dummy) t))
(message "I made this work"))
Run Code Online (Sandbox Code Playgroud)
我想要做的是检查之前是否a
有界限,如果已经绑定,则将其绑定到t
本地.否则根本不在乎a
.
代码失败为:(wrong-type-argument symbolp (if (boundp (quote a)) (quote a) (quote dummy)))
,表示let
特殊形式*不评估该参数(尽管该列表将评估为符号,但列表本身不是符号).
这是一个简单但有缺陷的替代方法,它为a
无论如何创建本地绑定,但如果它最初未绑定,则在本地范围内取消绑定.
(let ((a (if (boundp 'a) t nil)))
(or a (makunbound 'a))
;; do things
)
Run Code Online (Sandbox Code Playgroud)
缺点是,如果a
最初是未绑定的,那么您希望a
在该局部范围内的分配比本地范围更长,并且不会采用这种方法.
最初我认为你需要let
完全放弃解决这个问题,并使用这样的东西:
(when (boundp 'a)
(setq a-backup a
a t))
;; do things
(when (boundp 'a-backup)
(setq a a-backup)
(makunbound 'a-backup))
Run Code Online (Sandbox Code Playgroud)
然后我意识到,就像许多事情一样,宏是答案:
(defmacro let-if-bound (var value &rest body)
"Bind variable VAR to VALUE only if VAR is already bound."
(declare (indent 2))
`(if (boundp ',var)
(let ((,var ,value))
,@body)
(progn ,@body)))
(let-if-bound a t
;; do things
)
Run Code Online (Sandbox Code Playgroud)
(*)"特殊形式"是一种特殊标记的原始函数,因此它的参数不会全部被评估.大多数特殊形式定义控制结构或执行变量绑定 - 功能无法做到的事情.
每种特殊形式都有自己的规则,可以对哪些参数进行评估,哪些参数在没有评估的情 是否评估特定参数可能取决于评估其他参数的结果.
归档时间: |
|
查看次数: |
442 次 |
最近记录: |