带有命名参数的 Lisp 字符串格式化
Lisp string formatting with named parameters
Lisp 中有没有一种方法可以使用命名参数格式化字符串?
也许有一些像
这样的关联列表
(format t "All for ~(who)a and ~(who)a for all!~%" ((who . "one")))
为了打印"All for one and one for all"
.
类似于this python question, or this scala one, or even c++,但在 Lisp 中。
如果语言中没有这个功能,有没有人有任何很酷的函数或宏可以完成同样的事情?
使用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))))
替代reader函数
之前,我全局设置 *interpolate-format-directives*
,它解释所有内插字符串中的格式指令。
如果你想精确控制插入格式指令的时间,你不能只是在你的代码中临时绑定变量,因为魔法发生在读取时。相反,您必须使用自定义 reader 函数。
(set-dispatch-macro-character
#\#
#\F
(lambda (&rest args)
(let ((cl-interpol:*interpolate-format-directives* t))
(apply #'cl-interpol:interpol-reader args))))
如果我将特殊变量重置为其默认值 NIL,那么指令格式化的字符串将以 #F
为前缀,而普通的内插字符串使用 #?
语法。如果您想更改可读表,请查看 named readtables.
Lisp 中有没有一种方法可以使用命名参数格式化字符串?
也许有一些像
这样的关联列表(format t "All for ~(who)a and ~(who)a for all!~%" ((who . "one")))
为了打印"All for one and one for all"
.
类似于this python question, or this scala one, or even c++,但在 Lisp 中。
如果语言中没有这个功能,有没有人有任何很酷的函数或宏可以完成同样的事情?
使用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))))
替代reader函数
之前,我全局设置 *interpolate-format-directives*
,它解释所有内插字符串中的格式指令。
如果你想精确控制插入格式指令的时间,你不能只是在你的代码中临时绑定变量,因为魔法发生在读取时。相反,您必须使用自定义 reader 函数。
(set-dispatch-macro-character
#\#
#\F
(lambda (&rest args)
(let ((cl-interpol:*interpolate-format-directives* t))
(apply #'cl-interpol:interpol-reader args))))
如果我将特殊变量重置为其默认值 NIL,那么指令格式化的字符串将以 #F
为前缀,而普通的内插字符串使用 #?
语法。如果您想更改可读表,请查看 named readtables.