Return 来自循环内的格式
Return from format inside loop
我是 Lisp 新手,在理解 loop
和 format
组合时的工作原理时遇到了一些困难。
这符合我的预期:
(loop for i upto 2 do (format t "~a" "Badger")) ==>
BadgerBadgerBadger
NIL
这不是:
(loop for i upto 2 do (format nil "~a" "Badger")) ==>
NIL
为什么第二个循环不是 return BadgerBadgerBadger
?我必须编写什么代码才能赋予此 return 值?
这取决于format
函数的第一个参数,叫做destination(见manual):
If destination is a string, a stream, or t
, then the result is nil. Otherwise, the result is a string containing the ‘output’
在第一种情况下,format
写入标准输出(您会看到三个 "Budger")和 returns NIL
。但是您看不到 那个 值,而是 return 由 loop
编辑的值,即 NIL
。事实上,LOOP
中没有子句(如 RETURN
)到 return 与 NIL
不同的东西。
第二种情况,format
return是字符串,但是循环的值又是NIL
,就是整个表格的结果。
如果你想return格式的结果,你可以,例如,写:
(with-output-to-string (s)
(loop for i upto 2 do (format s "~a" "Badger")))
这样,format
函数"write"到字符串流s
,由with-output-to-string
编辑return。
return输入值和打印值之间存在重要区别。有时这在 REPL 中会造成混淆,因为 return 值默认打印:
CL-USER> (+ 1 1) ; form *returns* 2
2 ; and return value (2) is printed
CL-USER> (let ()
(+ 1 1) ; (+ 1 1) still returns 2, but
nil) ; the return value of the (let ...) is NIL
NIL ; so NIL is printed
现在,格式可以做一些不同的事情,这取决于它的第一个参数。如果它的第一个参数是 t 或一个流,那么它将输出写入流并且 returns nil:
CL-USER> (format t "hello")
hello ; printed output
NIL ; return value from format
CL-USER> (let ()
(format t "hello") ; will print "hello"
42) ; but the whole form returns 42
hello ; printed output
42 ; printed return value
当使用 nil 作为第一个参数调用 format 时,它 returns 作为字符串生成的输出:
CL-USER> (format nil "hello")
"hello" ; return value, not printed output
CL-USER> (let ()
(format nil "hello") ; returns "hello"
42) ; but the whole form returns 42
42 ; printed return value
现在,你可以收集循环的结果,听起来你想用格式生成一个字符串,然后收集那些字符串:
CL-USER> (loop for i upto 2 collect i)
(0 1 2)
CL-USER> (loop for i upto 2 collect (* 8 i))
(0 8 16)
CL-USER> (loop for i upto 2 collect (format nil "string number ~a" i))
("string number 0" "string number 1" "string number 2")
我是 Lisp 新手,在理解 loop
和 format
组合时的工作原理时遇到了一些困难。
这符合我的预期:
(loop for i upto 2 do (format t "~a" "Badger")) ==>
BadgerBadgerBadger
NIL
这不是:
(loop for i upto 2 do (format nil "~a" "Badger")) ==>
NIL
为什么第二个循环不是 return BadgerBadgerBadger
?我必须编写什么代码才能赋予此 return 值?
这取决于format
函数的第一个参数,叫做destination(见manual):
If destination is a string, a stream, or
t
, then the result is nil. Otherwise, the result is a string containing the ‘output’
在第一种情况下,format
写入标准输出(您会看到三个 "Budger")和 returns NIL
。但是您看不到 那个 值,而是 return 由 loop
编辑的值,即 NIL
。事实上,LOOP
中没有子句(如 RETURN
)到 return 与 NIL
不同的东西。
第二种情况,format
return是字符串,但是循环的值又是NIL
,就是整个表格的结果。
如果你想return格式的结果,你可以,例如,写:
(with-output-to-string (s)
(loop for i upto 2 do (format s "~a" "Badger")))
这样,format
函数"write"到字符串流s
,由with-output-to-string
编辑return。
return输入值和打印值之间存在重要区别。有时这在 REPL 中会造成混淆,因为 return 值默认打印:
CL-USER> (+ 1 1) ; form *returns* 2
2 ; and return value (2) is printed
CL-USER> (let ()
(+ 1 1) ; (+ 1 1) still returns 2, but
nil) ; the return value of the (let ...) is NIL
NIL ; so NIL is printed
现在,格式可以做一些不同的事情,这取决于它的第一个参数。如果它的第一个参数是 t 或一个流,那么它将输出写入流并且 returns nil:
CL-USER> (format t "hello")
hello ; printed output
NIL ; return value from format
CL-USER> (let ()
(format t "hello") ; will print "hello"
42) ; but the whole form returns 42
hello ; printed output
42 ; printed return value
当使用 nil 作为第一个参数调用 format 时,它 returns 作为字符串生成的输出:
CL-USER> (format nil "hello")
"hello" ; return value, not printed output
CL-USER> (let ()
(format nil "hello") ; returns "hello"
42) ; but the whole form returns 42
42 ; printed return value
现在,你可以收集循环的结果,听起来你想用格式生成一个字符串,然后收集那些字符串:
CL-USER> (loop for i upto 2 collect i)
(0 1 2)
CL-USER> (loop for i upto 2 collect (* 8 i))
(0 8 16)
CL-USER> (loop for i upto 2 collect (format nil "string number ~a" i))
("string number 0" "string number 1" "string number 2")