json - ST-JSON JSO 对象的解构宏

标签 json macros lisp common-lisp ccl

我还有一个关于在 Common Lisp 中解码 JSON 的问题。我选择了 ST-JSON 作为我的工具。我能够获取包含 JSON 数据的 JSO 对象,并使用 st-json:getjso 访问所有字段。我想写一个原则上类似于 destructuring-bind 的宏,它将为以 JSON 字段命名的变量提供本地绑定(bind)(从那时起我开始怀疑这是否是个好主意,但这是一个不同的问题) .我想出了以下内容:

(defmacro destructure-jso (jso &body body)
  (let (keys values)
    (st-json:mapjso #'(lambda (key value)
            (push key keys)
            (push value values))
            jso)
    `(destructuring-bind ,keys ,values
       ,@body)))

但是当我尝试在 JSO 对象上使用它时,出现错误 The value PARAMS is not of the expected type STRUCTURE. where PARAMS 是对象。谁可以给我解释一下这个?

谢谢。

最佳答案

显然,您正在像这样使用 destructure-jso:

(let ((params (st-json:read-json-from-string "{\"foo\":42,\"bar\":\"baz\"}")))
  (destructure-jso params
    (list foo bar)))

但是,destructure-jso 作为一个宏,在宏扩展时得到处理,甚至在 JSON 被解析之前。 params 作为符号传递给您的宏,没有被评估;即使尝试对其进行评估,它也将不受约束。

所以,如果你想写一个destructure-jso,你将需要宏扩展时的键列表。您可以以正常方式传递列表:

> (defmacro destructure-jso-2 (vars json &body body)
    `(let ,(mapcar #'(lambda (var)
                       (list var `(getjso ,(string-downcase (symbol-name var)) ,json)))
                   vars)
       ,@body))
DESTRUCTURE-JSO-2

> (let ((params (st-json:read-json-from-string "{\"foo\":42,\"bar\":\"baz\"}")))
    (destructure-jso-2 (foo bar)
    params
  (list foo bar)))
(42 "baz")

或者,如果您愿意,可以使用"template"JSON 来创建映射:

> (defmacro destructure-jso-3 (template json &body body)
    (let (bindings)
      (st-json:mapjso #'(lambda (key val)
                          (declare (ignore val))
                          (push (list (intern (string-upcase key)) `(getjso ,key ,json))
                                bindings))
                      (st-json:read-json-from-string template))
      `(let ,bindings
         ,@body)))
DESTRUCTURE-JSO-3

> (let ((params (st-json:read-json-from-string "{\"foo\":42,\"bar\":\"baz\"}")))
    (destructure-jso-3 "{\"foo\":null,\"bar\":null}"
        params
      (list foo bar)))
(42 "baz")

在这里,变量绑定(bind)来自第一个(模板)JSON,值来自第二个。模板 JSON 在宏扩展时解析,params JSON 每次执行您的代码时。

我不知道这两种方法是否对您有用。

关于json - ST-JSON JSO 对象的解构宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23266924/

相关文章:

assembly - 在 Emacs Lisp 中使用 asm-mode 识别 C++ 风格的注释

javascript - 理解 scheme 中的 fold 和 reduce 函数

functional-programming - 寻找 Church 编码(lambda 演算)来定义 < , > , !=

json - EDI X12 到 JSON 解析器 Python 3.5 可用吗?

c++ - c++ : #define MBGL_DEFINE_ENUM(T, 值中的省略号是什么...)?

jquery - 使用 jQuery 的 $.ajax() 将多个 Json 对象作为数据传递

c - visual c++ 与 gcc/clang 中的不同行为,同时对包含逗号的参数进行字符串化

c++ - 避免重新定义宏定义的类

python - 遍历 JSON - 列表索引上出现类型错误

c# - 区分 byte[] 和 string 与 JSON .NET