(defmacro switch [choices choice] '(do (choices choice)))
(macroexpand-1 '(switch {1 (print 1) 2 (print 2)} (+ 1 1)))
gives: (do (choices choice))
为了学习宏,我想模拟switch case,我将给出一个字典,其中case作为键,代码作为值执行。
我希望(+ 1 1)被评估为2然后被用作密钥以使用do执行codde。
然而,扩展的宏为我们提供了无法解决选择和选择的代码。
我尝试了无选择和选择,不起作用。 我在这里缺少什么?
答案 0 :(得分:3)
Unquoting确实有效,但您需要从常规报价切换到语法报价(反引号)以供引用:
(defmacro switch [choices choice]
`(do (~choices ~choice)))
请注意,这里不需要do
。
请注意,对于此版本的switch
,您的示例中的两个print
调用都将进行评估,因为它们只会在switch的输出中的地图文字中显示为值表达式。要有条件地打印,您必须使用一些条件构造(if
,case
或扩展为其中一个的条件构造。我还要指出choices
参数必须是文字映射,否则宏将无法获取键和值(并且在任何情况下,值都将由外部评估上下文)。
这是一个用以上内容编写的版本:
(defmacro switch [choices choice]
`(case ~choice ~@(apply concat choices)))
REPL的例子:
user=> (switch {1 (print 1) 2 (print 2)} (+ 1 1))
2nil
(2
打印print
,nil
是返回值。)