1
 (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,然后用作让 codede 执行 do 的关键。

然而,扩展宏为我们提供了不能同时解决选择和选择的代码。

我尝试取消引用选择和选择,但不起作用。我在这里想念什么?

4

1 回答 1

3

取消引用确实有效,但您需要从常规引用切换到语法引用(反引号)以进行引用:

(defmacro switch [choices choice]
  `(do (~choices ~choice)))

请注意,do此处是不必要的。

请注意,使用此版本的switch,您的示例中的两个print调用都将被评估,因为它们将简单地作为值表达式出现在 switch 输出中的映射文字中。要有条件地打印,您必须使用一些条件构造(ifcase扩展为其中之一的东西)。我还要指出,choices参数必须是文字映射,否则宏将无法获取键和值(并且在任何情况下,值都将由外部上下文评估)。

这是一个考虑到上述内容的版本:

(defmacro switch [choices choice]
  `(case ~choice ~@(apply concat choices)))

来自 REPL 的示例:

user=> (switch {1 (print 1) 2 (print 2)} (+ 1 1))
2nil

2print调用打印,nil是返回值。)

于 2013-07-09T19:10:36.297 回答