是否可以使用lisp的宏进行字符串插值?
例如,我可以制作这样的宏:
(defmacro test (a) `",a")
这样(测试abc)将“abc”作为字符串返回?我可以通过引用它并将该引号转换为字符串来作弊,但这不适用于像“9:00”这样的参数(没有双引号)。
答案 0 :(得分:3)
反对,无论是否在宏观中,都不会这样做:
[1]> (defmacro test (a) `",a")
TEST
[2]> (test oh-no)
",a"
您可以使用format
,如下所示:
[3]> (defun interp (name) (format nil "Hi, my name is ~A" name))
INTERP
[4]> (interp "Steve")
"Hi, my name is Steve"
答案 1 :(得分:3)
Lisp宏对lisp读者已经读过的参数进行操作。因为宏不能改变它的参数读取方式,并且如果你传递一个参数,当你试图读取它时会发出错误信号,例如9:00
中的(test 9:00)
,读者会在宏开始运行之前发出错误信号。
读者也可以自定义。不能让您以简单的方式阅读9:00
"9:00"
,但是例如,您可以编写一个简短的阅读器宏,将@9:00
读为"9:00"
或作为约会对象。
编辑:这样的事情:
(defvar *arguments-rt* (copy-readtable ()))
(defun timestring-reader (stream char &optional count)
(declare (ignore char count))
(with-output-to-string (s)
(loop repeat 4 do (write-char (read-char stream) s))))
(set-macro-character #\@ #'timestring-reader () *arguments-rt*)
(let ((*readtable* *arguments-rt*))
(let ((args "dinner @9:00"))
(with-input-from-string (stream args)
(loop for arg = (read stream () ())
while arg collect arg))))
-> (DINNER "9:00")
答案 2 :(得分:2)
对于字符串插值,请参阅format
。例如。 (format nil "~a" a)
做你想做的事。在Practical Common Lisp中有一些format recipes
quasiquote和unquote 仅适用于列表,而不适用于其他序列。
宏是代码的转换..它不是运行时发生的事情。例如。如果你有(my-macro x)
之类的代码,其中x
在运行时将是一个字符串,宏只能看到符号。它无法知道它在扩展时的类型。