带参数的 Lisp 格式列表

Lisp format list with parameter

我正在尝试创建一个函数来获取字符串并显示它。

(defun closing (s)
  (format t "~{~a~}" ("Sincerely," "\n" s)))

我希望得到的是

Sincerely,

Frank

if "Frank" 是我传入的字符串。它抱怨变量 S 已定义但从未使用过。我做错了什么?

尝试单独使用格式:如果我将 urname 作为 defparameter 声明为 "Frank",则以下内容不会打印 Frank,而只会打印变量名称。 (没有引用它抱怨 urname 不是一个函数。)

(format t "~{~a~}" '(urname urname urname))

如何为格式提供变量?

这里存在三个问题:(1)你贴的代码不只是没有使用s的问题;它还试图将 string "Sincerely" 作为函数调用; (2) 引用一个列表意味着你会得到被引用的确切内容(例如,符号列表,而不是变量值列表); (3) 列表调用格式

(something other-stuff...) 是一个函数调用

当我将您发布的代码放入 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

("Sincerely," "\n" s) 是非法函数调用,因为 string,如 "Sincerely",不能有函数绑定。由于 SBCL 看到了其中的问题,它认识到 s 可能用于的一件事(即函数调用的参数)不会发生。这就是为什么你会得到错误,然后是相关的样式警告。

创建值列表

第二个问题可能已经在其他问题中得到解答,但简短的回答是您想要 (list x y z),而不是 '(x y z)。前者使用 variables x[= 的 values 调用函数 list 59=]、yz,而后者表示 符号 xyz.

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) 

格式、迭代等

第三个可能更有趣,因为 format 有很多可能性。您示例中的 ~{ 和 ~} 用于迭代列表中的值。首先,让我们看一个简单的例子:你可以只使用格式指令 ~a 并用你想要拼接的参数调用格式:

CL-USER> (let ((closing "Sincerely")
               (name "Frank"))
           (format t "~a,~%~a" closing name))
Sincerely,
Frank

现在,如果您需要打印多个值,您可以使用 ~{ 和 ~} 让格式迭代值列表:

CL-USER> (let ((closing "Sincerely")
               (names '("Frank" "John")))
           (format t "~a,~{~%~a~}" closing names))
Sincerely,
Frank
John

如果名称是变量的值,那么您可以创建一个包含这些值的列表:

CL-USER> (let ((closing "Sincerely")
               (name1 "Frank")
               (name2 "John"))
           (format t "~a,~{~%~a~}" closing (list name1 name2)))
Sincerely,
Frank
John

或者您可以将 ~{ 更改为 ~@{ 并将格式读取 remaining 参数作为列表:

CL-USER> (let ((closing "Sincerely")
               (name1 "Frank")
               (name2 "John"))
           (format t "~a,~@{~%~a~}" closing name1 name2))
Sincerely,
Frank
John

您应该阅读有关格式的教程,例如 here

为了简单的解释

(格式 (destination-stream通常t为标准输出nil组成一个字符串) (字符串来了) (&rest 变量应该写在字符串中,其中 ~A 和 String.format 在 java 或 c 中的位置))

在你的情况下,你需要符号 ~% 或在 common lisp

中使用 return 字符
CL-USER> (defun closing (s) (format t "~A~%~%~A" "Sincerely," s))
CLOSING
CL-USER> (closing "paco")
Sincerely,

paco
NIL

nil表示函数returns为null,另外一个是标准输出,如果要return一个字符串,就把nil代替t