如何在没有实际打印的情况下从(错误)对象生成字符串?

时间:2013-10-13 01:07:38

标签: common-lisp sbcl

我想检索由write生成的字符串,以便进行进一步处理而不进行任何实际输出,但write似乎总是也输出到REPL

CL-USER>(let ((err-string (write (make-instance 'error) :stream nil)))
          (do-awesome-stuff-with-string err-string))
<ERROR> ;;this is the printing I want to get rid of
"awesome-result"

为什么write仍会输出到REPL中,如何摆脱它?

2 个答案:

答案 0 :(得分:6)

您可以使用with-output-to-string。这是一个例子:

(flet ((do-awesome-stuff-with-string (string)
         (concatenate 'string string " is awesome!")))
  (let ((err-string (with-output-to-string (s)
                      (write (make-instance 'error) :stream s))))
    (do-awesome-stuff-with-string err-string)))
;; => "#<ERROR {25813951}> is awesome!"

这是[{1}}上的here's HyperSpec条目。

with-output-to-string不起作用的原因是(write (make-instance 'error) :stream nil)的{​​{1}}参数是stream designator,在该上下文中:stream是{{}的简写1}}。 (write代替nil意味着它应该返回一个字符串这一事实是一个常见的混淆点。)

答案 1 :(得分:3)

请注意,使用MAKE-CONDITION可以轻松导致错误。该标准并未说明错误是CLOS类,因此MAKE-INSTANCE在某些实现中可能不起作用。

获取字符串有两种简单方法:

a)文字说明:

CL-USER 15 > (princ-to-string (make-condition 'error))
"The condition #<ERROR 4020311270> occurred"

b)打印错误对象:

CL-USER 16 > (prin1-to-string (make-condition 'error))
"#<ERROR 402031158B>"
相关问题