列表上的格式:使用不在列表中的参数
Format over list: use arguments that aren't in list
这是我写的一个代码片段,但不起作用:
(let ((separator "|")
(text '("Just" "do" "it" "!")))
(format t "~{~A~A~%~}" text separator))
输出应如下所示:
Just|
do|
it|
!|
但是,它不会那样工作 - 当我在 ~{~}
中时,我不知道如何从列表外部添加元素。我可以这样做:
(format t "~{~A|~%~}" text)
但这不允许我使用变量中的 separator
,这就是我所追求的。
现在我知道我可以通过在每个偶数位置添加分隔符来合并 text
和分隔符,但这对我来说很难看。在 format
中还有其他方法吗?
这是一个技巧:
CL-USER 49 > (let ((separator "|")
(text '("Just" "do" "it" "!")))
(format t
(concatenate 'string "~{~A" separator "~%~}")
text))
Just|
do|
it|
!|
在分隔符字符串中转义波浪号:
CL-USER 56 > (flet ((fix-tilde (string)
(with-output-to-string (s)
(loop for c across string
when (char= c #\~)
do (write-string "~~" s)
else do (write-char c s)))))
(let ((separator (fix-tilde "~a~a"))
(text '("Just" "do" "it" "!")))
(format t
(concatenate 'string "~{~A" separator "~%~}")
text)))
Just~a~a
do~a~a
it~a~a
!~a~a
您可以使用 Tilde Slash 格式指令,它允许将用户定义的函数用作格式说明符。这只是给你一个可能的例子,很多变化都是可能的:
CL-USER> (defvar *separator* " ")
*SEPARATOR*
CL-USER> (defun q(stream arg &rest args)
(declare (ignore args))
(format stream "~a~a" arg *separator*))
Q
CL-USER> (let ((*separator* "|")
(text '("Just" "do" "it" "!")))
(format t "~{~/q/~%~}" text))
Just|
do|
it|
!|
NIL
CL-USER> (let ((*separator* "+++")
(text '("Just" "do" "it" "!")))
(format t "~{~/q/~%~}" text))
Just+++
do+++
it+++
!+++
NIL
CL-USER>
稍微更改一下 renzo 的回答:如果我们使用 SPECIAL 声明,则不需要全局变量:
(defun %d1 (stream arg &rest args)
(declare (ignore args)
(special delim))
(princ arg stream)
(princ delim stream))
(defun my-print (list delim)
(declare (special delim))
(format nil "~{~/%d1/~%~}" list))
这是我写的一个代码片段,但不起作用:
(let ((separator "|")
(text '("Just" "do" "it" "!")))
(format t "~{~A~A~%~}" text separator))
输出应如下所示:
Just|
do|
it|
!|
但是,它不会那样工作 - 当我在 ~{~}
中时,我不知道如何从列表外部添加元素。我可以这样做:
(format t "~{~A|~%~}" text)
但这不允许我使用变量中的 separator
,这就是我所追求的。
现在我知道我可以通过在每个偶数位置添加分隔符来合并 text
和分隔符,但这对我来说很难看。在 format
中还有其他方法吗?
这是一个技巧:
CL-USER 49 > (let ((separator "|")
(text '("Just" "do" "it" "!")))
(format t
(concatenate 'string "~{~A" separator "~%~}")
text))
Just|
do|
it|
!|
在分隔符字符串中转义波浪号:
CL-USER 56 > (flet ((fix-tilde (string)
(with-output-to-string (s)
(loop for c across string
when (char= c #\~)
do (write-string "~~" s)
else do (write-char c s)))))
(let ((separator (fix-tilde "~a~a"))
(text '("Just" "do" "it" "!")))
(format t
(concatenate 'string "~{~A" separator "~%~}")
text)))
Just~a~a
do~a~a
it~a~a
!~a~a
您可以使用 Tilde Slash 格式指令,它允许将用户定义的函数用作格式说明符。这只是给你一个可能的例子,很多变化都是可能的:
CL-USER> (defvar *separator* " ")
*SEPARATOR*
CL-USER> (defun q(stream arg &rest args)
(declare (ignore args))
(format stream "~a~a" arg *separator*))
Q
CL-USER> (let ((*separator* "|")
(text '("Just" "do" "it" "!")))
(format t "~{~/q/~%~}" text))
Just|
do|
it|
!|
NIL
CL-USER> (let ((*separator* "+++")
(text '("Just" "do" "it" "!")))
(format t "~{~/q/~%~}" text))
Just+++
do+++
it+++
!+++
NIL
CL-USER>
稍微更改一下 renzo 的回答:如果我们使用 SPECIAL 声明,则不需要全局变量:
(defun %d1 (stream arg &rest args)
(declare (ignore args)
(special delim))
(princ arg stream)
(princ delim stream))
(defun my-print (list delim)
(declare (special delim))
(format nil "~{~/%d1/~%~}" list))