我想知道是否有可能从类似于(伪代码)的循环中动态构建COND子句:
(defvar current-state 1)
(defmacro mymacro ()
(cond
`(loop (state . callback) in possible-states
do ((eq current-state ,state)
(funcall ,callback)))))循环将从列表中构建子句,并生成如下内容:
(cond
((eq current-state 1)
(funcall func-1))
((eq current-state 2)
(funcall func-2))
((eq current-state 3)
(funcall func-3)))发布于 2019-02-22 15:53:04
宏在编译时被展开,所以您的possible-states变量必须是编译时常量.如果情况并非如此(或者您对我上面的意思不完全清楚),您应该在这里使用而不是的宏。
使用函数代替:
(funcall (cdr (find current-state possible-states :key #'car :test #'eq)))或
(funcall (cdr (assoc current-state possible-states :test #'eq)))或者,更好的是,让您的possible-states成为hash table而不是association list
(funcall (gethash current-state possible-states))但是,如果您的possible-states 是编译时间常数,则确实可以使用宏,但您可能希望使用case而不是cond。
(defmacro state-dispatch (state)
`(case ,state
,@(mapcar (lambda (cell)
`((,(car cell)) (,(cdr cell))))
possible-states)))
(defparameter possible-states '((1 . foo) (2 . bar)))
(macroexpand-1 '(state-dispatch mystate))
==> (CASE MYSTATE ((1) (FOO)) ((2) (BAR))) ; T请注意,从速度的角度来看,gethash版本可能与宏版本相同(至少它并不慢)。
https://stackoverflow.com/questions/54830186
复制相似问题