惊喜打印到字符串(常见的lisp)

Reb*_*bin 3 common-lisp

按照WITH-OUTPUT-TO-STRINGGET-OUTPUT-STREAM-STRING的文档,我希望以下内容可以正常工作,它们可以:

(print
 (with-output-to-string (sb nil)
   (format sb "~A " "hello, ")
   (format sb "~A~&" "world")
   sb))

(print
 (let ((sb (make-string-output-stream)))
   (format sb "~A " "hello, ")
   (format sb "~A~&" "world")
   (get-output-stream-string sb)))
Run Code Online (Sandbox Code Playgroud)

但是,以下内容与WITH-OUTPUT-TO-STRING中的一个示例相近 ,不会:

(print
 (with-output-to-string (sb (make-array
                             '(0)
                             :element-type 'base-char
                             :fill-pointer 0
                             :adjustable t))
   (format sb "~A " "hello, ")
   (format sb "~A~&" "world")
   sb))
Run Code Online (Sandbox Code Playgroud)

相反,生成输出流本身,而不是生成的字符串:

#<SB-IMPL::FILL-POINTER-OUTPUT-STREAM {1005FBE523}>
Run Code Online (Sandbox Code Playgroud)

我一直无法找到在输出流中提取字符串的方法.我怀疑它与动态范围有关,但我的理解在这里踌躇不前.

显然,我有更好的方法来达到预期的结果,所以我只是好奇地发现我对语言的误解.

由于文件说,结果是不确定的,用于在流GET-OUTPUT-STREAM-STRING 不是由MAKE-STRING-OUTPUT-STREAM创建的,我并不感到惊讶,下面不工作:

(print
 (with-output-to-string (sb (make-array
                             '(0)
                             :element-type 'base-char
                             :fill-pointer 0
                             :adjustable t))
   (format sb "~A " "hello, ")
   (format sb "~A~&" "world")
   (get-output-stream-string sb)))
Run Code Online (Sandbox Code Playgroud)

但我仍然很感激在第三个例子中找到一种提取字符串的方法.

Rai*_*wig 7

请注意,WITH-OUTPUT-TO-STRING以两种不同的方式返回值:

  1. 如果你没有给它字符串NIL,那么它会创建一个字符串并返回它.
  2. 如果你给它一个字符串,那么它返回最后一个体形的结果值.

你的代码:

(print
 (with-output-to-string (sb (make-array   ; creates a string
                             '(0)
                             :element-type 'base-char
                             :fill-pointer 0
                             :adjustable t))
   (format sb "~A " "hello, ")
   (format sb "~A~&" "world")
   sb)   ; you return the stream (which makes not much sense), but not the string
   )
Run Code Online (Sandbox Code Playgroud)

您已通过调用创建了一个字符串MAKE-ARRAY.它就是.用它.为此,您通常需要将其绑定到某个变量.

示例如何返回字符串:

(let ((s (make-array '(0)
                     :element-type 'base-char
                     :fill-pointer 0
                     :adjustable t)))
  (with-output-to-string (sb s)
    (format sb "~A " "hello, ")
    (format sb "~A~&" "world"))
  s)
Run Code Online (Sandbox Code Playgroud)

要么

(let ((s (make-array '(0)
                     :element-type 'base-char
                     :fill-pointer 0
                     :adjustable t)))
  (with-output-to-string (sb s)
    (format sb "~A " "hello, ")
    (format sb "~A~&" "world")
    s))
Run Code Online (Sandbox Code Playgroud)

在最后一种情况下with-output-to-string返回值,因为它有一个字符串,它用作输出的目标.

  • @ Reb.Cabin:如果你没有传递任何内容或NIL,将返回该字符串.如果传递字符串,将返回最后一个表单的值.在第一个示例中,忽略sb的值. (4认同)