147*_*7pm 0 format common-lisp
我正在尝试创建一个函数,该函数将接受一个字符串并显示它。
(defun closing (s)
(format t "~{~a~}" ("Sincerely," "\n" s)))
Run Code Online (Sandbox Code Playgroud)
我希望得到的是
真挚地,
坦率
如果“弗兰克”是我传入的字符串。它抱怨变量 S 已定义但从未使用过。我究竟做错了什么?
尝试单独使用格式:如果我urname将 defparameter声明为“Frank”,则以下内容不会打印 Frank,而只是变量名称。(没有引用它抱怨 urname 不是一个函数。)
(format t "~{~a~}" '(urname urname urname))
Run Code Online (Sandbox Code Playgroud)
如何提供变量以进行格式化?
这里存在三个问题:(1)您发布的代码不仅存在不使用s的问题;它还试图将字符串 “Sincerely”作为函数调用;(2) 引用列表意味着您将得到引用的内容(例如,符号列表,而不是变量值列表);(3) 带列表的调用格式。
当我将您发布的代码放入 SBCL 时,我得到了一些非常具体且有用的输出:
CL-USER> (defun closing (s)
(format t "~{~a~}" ("Sincerely," "\n" s)))
; in: DEFUN CLOSING
; ("Sincerely," "n" S)
;
; caught ERROR:
; illegal function call
; (SB-INT:NAMED-LAMBDA CLOSING
; (S)
; (BLOCK CLOSING (FORMAT T "~{~a~}" ("Sincerely," "n" S))))
;
; caught STYLE-WARNING:
; The variable S is defined but never used.
;
; compilation unit finished
; caught 1 ERROR condition
; caught 1 STYLE-WARNING condition
Run Code Online (Sandbox Code Playgroud)
("Sincerely," "\n" s)是非法的函数调用,因为像"Sincerely"这样的string不能绑定函数。由于 SBCL 看到了问题所在,它认识到s可能已用于的一件事(即函数调用的参数)不可能发生。这就是为什么您会收到错误,然后是相关的样式警告。
第二个可能已经在其他问题中得到了回答,但简短的回答是你想要(list xyz),而不是'(xyz)。前者呼叫的功能列表与所述值的的变量 X,ÿ,和Ž,而后者表示的文字列表的符号 X,ÿ,和ž。
CL-USER> (let ((a 42)
(b 89))
(print '(a b)) ; a list of two symbols
(print (list a b))) ; a list of two numbers
(A B)
(42 89)
Run Code Online (Sandbox Code Playgroud)
第三个可能更有趣,因为格式有很多可能性。示例中的 ~{ 和 ~} 用于迭代列表中的值。首先,让我们看一个简单的例子:你可以只使用格式指令 ~a 并使用你想要拼接的参数调用格式:
CL-USER> (let ((closing "Sincerely")
(name "Frank"))
(format t "~a,~%~a" closing name))
Sincerely,
Frank
Run Code Online (Sandbox Code Playgroud)
现在,如果你需要打印多个值,你可以使用 ~{ 和 ~} 来让格式迭代一个值列表:
CL-USER> (let ((closing "Sincerely")
(names '("Frank" "John")))
(format t "~a,~{~%~a~}" closing names))
Sincerely,
Frank
John
Run Code Online (Sandbox Code Playgroud)
如果名称是变量的值,那么您可以创建一个包含这些值的列表:
CL-USER> (let ((closing "Sincerely")
(name1 "Frank")
(name2 "John"))
(format t "~a,~{~%~a~}" closing (list name1 name2)))
Sincerely,
Frank
John
Run Code Online (Sandbox Code Playgroud)
或者您可以将 ~{ 更改为 ~@{ 并将格式读取剩余的参数作为列表:
CL-USER> (let ((closing "Sincerely")
(name1 "Frank")
(name2 "John"))
(format t "~a,~@{~%~a~}" closing name1 name2))
Sincerely,
Frank
John
Run Code Online (Sandbox Code Playgroud)