我需要生成一个带有可变字符串长度的空格填充字符串。不那么聪明的解决方案涉及嵌套format
:
(format nil (format nil "~~~d,,a" 10) "asdf")
现在,我希望通过使用format
' s ~?
进行递归处理,使其变得更加聪明。我希望像这样的东西应该做我想做的事情:
(format nil "~@?" "~~~d,,a" 10 "asdf")
但我得到的只是格式化字符串,即~10,,a
,而不是填充的asdf
字符串。也许我误解了“递归”这个词。在这里,但我希望已经形成了内部格式字符串,CL应该继续实际使用它。我错过了什么吗?
答案 0 :(得分:5)
格式指令的变量参数
FORMAT
允许您使用v
作为控制字符串中指令的参数,以从参数列表中弹出参数。
CL-USER> (format nil "~va" 10 "asdf")
"asdf "
可能会使用多个v
。
CL-USER> (format nil "~v,,,va" 10 #\- "asdf")
"asdf------"
使用~?
递归处理指令用于在控件字符串中嵌入对FORMAT
的不同“调用”。例如,可以使用它来实现提示是或否答案的函数。
(defun y-or-n-prompt (control-string &rest args)
(format t "~&~? [y/n]: " control-string args)
;;...
)
调用者现在可以使用FORMAT
格式化提示,而不必担心提示应该对用户的详细信息(在开头添加新行或{{ 1}}提示结束)。
[y/n]:
CL-USER> (y-or-n-prompt "foo ~d bar" 12)
foo 12 bar [y/n]:
NIL
的结果将不会由~?
处理,因此无法用于构建控制字符串。通常,在运行时构建控制字符串是一个坏主意,因为它容易出错(例如,您必须转义字符串中任何不需要的波形)并阻止实现在编译时处理控制字符串。