带参数的 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=]、y 和 z,而后者表示 符号 x、y 和 z.
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
我正在尝试创建一个函数来获取字符串并显示它。
(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=]、y 和 z,而后者表示 符号 x、y 和 z.
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