在遍历一组格式化的子列表时,在最后一次迭代中省略一个字符
可以通过在最后一次迭代的格式化输出前面加上 ~^ 格式指令来省略一个字符:
(format nil "~{~A~^,~}" '(1 2 3))
;; -> "1,2,3"
也可以对一个子列表的列表进行迭代,逐个使用其中的每个子列表的值:
(format nil "~:{~A is for ~A. ~}" '(("A" "Alice") ("B" "Bob")))
;; -> "A is for Alice. B is for Bob. "
但将两者结合起来似乎行不通(在SBCL和 CLisp上测试过):
(format nil "[~:{[~d,~d]~^,~}]" '((1 2) (3 4)))
;; -> "[[1,2][3,4]]" instead of "[[1,2],[3,4]]"
有没有办法实现这一点?
解决方案
对于 ~:{(以及 ~:@{ 这样的构造,使用该目的的正确格式指令是 ~:^,而不是 ~^。
根据 CLHS的 2.3.9.2 "Tilde Circumflex: Escape Upward":
如果
~^在~:{构造中使用,则会终止当前迭代步骤,因为在标准情况下它只测试当前步骤的剩余参数;下一次迭代步骤会立即开始。~:^用于终止迭代过程。~:^仅在它将终止的命令是~:{或~:@{时才可使用。
所以看起来我可以直接执行以下操作:
(format nil "[~:{[~d,~d]~:^,~}]" '((1 2) (3 4)))
;; -> "[[1,2],[3,4]]"
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。