如何解决如何借助宏来解构一堆东西?
我必须在程序中defconst
设置64个值,并且鉴于Lisp具有我从未使用过的著名宏工具,我认为这是我的机会。但这似乎不像我预期的那样...
(defun square-name (square-index)
(multiple-value-bind (row col) (floor square-index 8)
(format nil "SQ-~A~D"
(string (code-char (+ (char-code #\A) col)))
(+ 1 row))))
(defmacro defconst-all-square-names ()
(dotimes (i 64)
`(defconstant,(make-symbol (square-name i)),i)))
(defconst-all-square-names)
鉴于我对lisp和宏特别陌生,有人可以解释一下,
- 如何在不自己键入常量的情况下实现定义常量的目标。
- 如果我不能使用宏,那为什么呢?
也许我只是想念一些宣告之类的话。上面的代码编译时没有警告或错误,并且在加载后(使用emacs,slim和CTRL-C-K进行了编译),均未定义任何常量。
更新
在与@Rainer Joswig聊天后(非常感谢!), 那
- 宏必须返回一个要执行的代码
- 我的
(make-symbol...)
构造并没有达到预期的效果,我不得不使用(intern...)
。
所有这些之后,工作代码现在看起来像这样:
(defun square-name (square-index)
(multiple-value-bind (row col) (floor square-index 8)
(format nil "SQ-~A~D" (string (code-char (+ (char-code #\A) col))) (+ 1 row))))
(defmacro defconst-all-square-names ()
(append '(progn)
(loop for i from 0 to 63 collect
`(defconstant,(intern (square-name i)),i))))
(defconst-all-square-names)
解决方法
让我们看看dotimes
:
* (dotimes (i 10) 42)
NIL
上面的dotimes
表单返回NIL
,与()
->空列表相同。基本上它什么也不返回。
因此您的宏不返回任何内容。因此,代码(defconst-all-square-names)
扩展为()
。用macroexpand-1
进行检查。
总结:
- 您的宏没有副作用
- 您的宏扩展为一个空列表,因为您的宏返回
()
您需要修复后者。
请记住:宏的首要目的是生成代码。 ->您需要生成代码,否则需要键入。由于您的宏确实返回了()
,并且运行()
自然不会产生任何效果->仍然没有任何反应。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。