带参数

时间:2015-09-18 16:36:24

标签: format common-lisp

我试图创建一个带字符串并显示它的函数。

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

我希望得到的是

  

此致

     

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

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

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

如何将变量提供给格式?

2 个答案:

答案 0 :(得分:4)

这里有三个问题:(1)您发布的代码并不存在不使用 s 的问题;它还试图将字符串 "真诚" 作为一个功能; (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

("此致"" \ n" s)是非法的函数调用,因为 string ,就像"真诚" ,无法进行功能绑定。由于SBCL看到了这个问题,它认识到 s 可能已用于的一件事(即函数调用的参数)不会发生。这就是为什么您会收到错误,然后是相关的样式警告。

创建值列表

第二个问题可能已在其他问题中得到解答,但简短的回答是你需要(list x y z),而不是'(x y z)。前者使用变量 x 调用函数列表 y z ,而后者表示符号的文字列表 x y ž

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) 

格式,迭代,& c。

第三个可能更有趣,因为格式有很多可能性。示例中的〜{和〜}用于迭代列表中的值。首先,让我们看一个简单的例子:你可以使用格式指令~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

或者您可以更改〜{to~ @ {并将格式读取剩余的参数作为列表:

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

答案 1 :(得分:2)

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

为了便于解释

(格式 (目标流通常为标准输出n为形成字符串) (这里是字符串) (& rest变量应写入字符串,其中是一个~A和位置,如java或c中的String.format))

在您的情况下,您需要符号〜%或使用该字符在常见的lisp中返回

CL-USER> (defun closing (s) (format t "~A~%~%~A" "Sincerely," s))
CLOSING
CL-USER> (closing "paco")
Sincerely,

paco
NIL

nil表示函数返回null,另一个是标准输出,如果你想返回一个字符串,把nil代替t