使用
CL-INTERPOL。
(cl-interpol:enable-interpol-syntax)
字符串插值
对于简单的情况,你不需要使用 FORMAT
:
(lambda (who) #?"All for $(who) and $(who) for all!")
然后:
(funcall * "one")
=> "All for one and one for all!"
解释格式指令
如果需要进行格式化,可以使用以下方法:
(setf cl-interpol:*interpolate-format-directives* t)
例如,这个表达式:
(let ((who "one"))
(princ #?"All for ~A(who) and ~S(who) for all!~%"))
...打印:
All for one and "one" for all!
如果你好奇,上面的内容可以这样理解:
(LET ((WHO "one"))
(PRINC
(WITH-OUTPUT-TO-STRING (#:G1177)
(WRITE-STRING "All for " #:G1177)
(FORMAT #:G1177 "~A" (PROGN WHO))
(WRITE-STRING " and " #:G1177)
(FORMAT #:G1177 "~S" (PROGN WHO))
(WRITE-STRING " for all!" #:G1177))))
替代读取器函数
以前,我全局设置了*interpolate-format-directives*
,它会解释所有插值字符串中的格式指令。
如果您想精确控制何时插入格式指令,您不能仅在代码中临时绑定变量,因为这种魔法发生在读取时。相反,您必须使用自定义读取器函数。
(set-dispatch-macro-character
#\#
#\F
(lambda (&rest args)
(let ((cl-interpol:*interpolate-format-directives* t))
(apply #'cl-interpol:interpol-reader args))))
如果我将特殊变量重置为其默认值NIL,则格式化指令的字符串前缀为#F
,而正常插值使用#?
语法。如果您想更改读取表,请查看命名读取表。
#"
读取器宏实现。https://lispcookbook.github.io/cl-cookbook/cl21.html#string-interpolation - Ehvince