使用特殊变量时使用宏会出错

问题描述 投票:0回答:1

SBCL 2.3.7

我不想写这样的格式,因为我有很多变量(超过3个)并且想在它们之间插入分号:

(format nil "~a;~b;~c;" var1 var2 var3)

预期结果:

"a;b;c;"

我定义了一个特殊变量和一个宏。

(defparameter *delimiter* ";")

(defmacro format-delimited (stream fmt delimiter &body vars)
   (let ((fmtstr ""))
    (dotimes (i (length vars))
      (setf fmtstr (str:concat fmtstr fmt delimiter)))
    `(format ,stream ,fmtstr ,@vars)))

本次调用成功返回:

(format-delimited nil "~a" ";" "a" "b" "c")
"a;b;c;"

macroexpand-1 返回:

(FORMAT NIL "~a;~a;~a;" "wolf" "golf" "rolf")

此调用以错误结束:

(format-delimited nil "~a" *delimiter* "a" "b" "c")

; Debugger entered on #<TYPE-ERROR expected-type: SEQUENCE datum: *DELIMITER*>

macroexpand-1 也以错误结束。

错误原因是什么?

macros lisp common-lisp
1个回答
0
投票

只需使用

format
已经提供的设施即可。您可以使用
~{ ~}
迭代参数列表:

CL-USER> (format nil "~{~A;~}" '("a" "b" "c"))
"a;b;c;"

如果要省略最后的分号,可以在处理完最终参数后使用

~^
来转义迭代:

CL-USER> (format nil "~{~A~^;~}" '("a" "b" "c"))
"a;b;c"
© www.soinside.com 2019 - 2024. All rights reserved.