我想将s-表达式转换为带有前缀符号的字符串format
。如何使用来完成format
?
例;
(format t "<insert format controls here>" (1 2 3) '*)
=> "1 * 2 * 3"
Run Code Online (Sandbox Code Playgroud)
此答案包含错误的代码。
简单,只需使用自定义格式器:
(format t "~/acquire/~/disseminate/" '(1 2 3) '*)
Run Code Online (Sandbox Code Playgroud)
它们的定义如下:
(let ((memory))
(defun cl-user::acquire (stream list &optional colonp atsignp)
(declare (ignore colonp atsignp stream))
(setf memory list))
(defun cl-user::disseminate (stream operator &optional colonp atsignp)
(declare (ignore colonp atsignp))
(format stream (concatenate 'string "~{~a~^ " (string operator) " ~}") memory)
(setf memory nil)))
Run Code Online (Sandbox Code Playgroud)
例如:
CL-USER> (format t "~/acquire/~/disseminate/" '(1 2 3) '*)
1 * 2 * 3
Run Code Online (Sandbox Code Playgroud)
的memory
变量是在这两者的功能,其允许它们进行通信数据的词法作用域。第一个存储列表,第二个使用列表。如果您从不调用第二个函数(或第一个带有nil的函数),memory
则永远将其绑定到最后一个列表,那可能是个问题。另请注意,您可能会遇到并发问题。坦白说,这不是您想要做的最好的方法,但是它可以根据您的要求完成工作。
(format t "~{~A~^ * ~}" '(1 2 3))
;; 1 * 2 * 3
;; NIL
Run Code Online (Sandbox Code Playgroud)
~{~}
:循环遍历列表。~A
:打印人可读(一个审美)~^
:仅当列表中有后继元素时才打印以下内容。*
:在周围的空白处加缀。我曾经问过类似的问题。您'*
在最后添加了-因此您还希望控制join
列表元素应使用哪个分隔符。查看以下链接-@Sylwester给出了可接受的答案:common-lisp中的pythonic`join`。
(他通过将第二个格式表达式注入格式表达式来做到这一点-非常优雅!-这样就可以调用(join '(1 2 3) :sep " * ")
)。