首页 > 解决方案 > 如何让 yason:encode-alist 返回编码字符串而不是将其发送到流?

问题描述

我正在尝试使用 YASON 对来自 alist 的 JSON 字符串进行编码。问题是,我得到的返回值是我喂它的原始 alist。它正在打印 JSON 字符串,根据文档,它转到*STANDARD-OUTPUT*.

简单的示例会话:

(ql:quickload :yason)
To load "yason":
  Load 1 ASDF system:
    yason
; Loading "yason"

(:YASON)
* (defparameter starving-json-eater (yason:encode-alist '(("foo" . "bar") ("baz" . "qux"))))
{"foo":"bar","baz":"qux"}
STARVING-JSON-EATER
* starving-json-eater

(("foo" . "bar") ("baz" . "qux"))

我尝试传递参数,但'starving-json-eater出现stream错误:

* (setf starving-json-eater (yason:encode-alist '(("foo" . "bar") ("baz" . "qux")) 'starving-json-eater))

debugger invoked on a SIMPLE-ERROR in thread
#<THREAD "main thread" RUNNING {1001E06783}>:
  There is no applicable method for the generic function
    #<STANDARD-GENERIC-FUNCTION SB-GRAY:STREAM-WRITE-CHAR (1)>
  when called with arguments
    (STARVING-JSON-EATER #\{).

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [RETRY] Retry calling the generic function.
  1: [ABORT] Exit debugger, returning to top level.

((:METHOD NO-APPLICABLE-METHOD (T)) #<STANDARD-GENERIC-FUNCTION SB-GRAY:STREAM-WRITE-CHAR (1)> STARVING-JSON-EATER #\{) [fast-method]

我怎样才能{"foo":"bar","baz":"qux"}进入starving-json-eater

标签: jsonencodingstreamcommon-lisp

解决方案


您可以使用WITH-OUTPUT-TO-STRING临时将变量绑定到写入字符串的打开流。您甚至可以绑定特殊变量*standard-output*,以便仅更改代码的动态上下文,而无需显式提供不同的流参数(例如当您使用进程重定向流时)。

(with-output-to-string (*standard-output*)
  (yason:encode-alist '(("a" . "b"))))

请注意,绑定*standard-output*意味着写入的任何内容*standard-output*最终都将在with-output-to-string. 在上述情况下,范围被充分限制以避免意外捕获嵌套代码的输出。您还可以使用词法变量来精确控制谁可以写入字符串:

(with-output-to-string (json)
  (yason:encode-alist '(("a" . "b")) json))

推荐阅读