Woj*_*Gac 1 lisp macros json common-lisp ccl
我还有一个关于在Common Lisp中解码JSON的问题.我决定采用ST-JSON
我的工具.我能够获得一个JSO
包含JSON数据的对象,并访问所有字段st-json:getjso
.我想编写一个原则上类似于宏的宏来destructuring-bind
提供对JSON字段之后命名的变量的局部绑定(从那以后我开始怀疑这是不是一个好主意,但这是一个不同的问题).我想出了以下内容:
(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)))
Run Code Online (Sandbox Code Playgroud)
但是当我尝试在JSO
对象上使用它时,我得到的错误The value PARAMS is not of the expected type STRUCTURE.
在哪里PARAMS
是对象.谁可以给我解释一下这个?
谢谢.
显然,你这样使用destructure-jso
:
(let ((params (st-json:read-json-from-string "{\"foo\":42,\"bar\":\"baz\"}")))
(destructure-jso params
(list foo bar)))
Run Code Online (Sandbox Code Playgroud)
但是,destructure-jso
作为一个宏,在宏扩展时处理,在JSON甚至被解析之前.params
作为符号传递给您的宏,而不进行评估; 即使尝试进行评估,它也是未受约束的.
因此,如果要编写a 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")
Run Code Online (Sandbox Code Playgroud)
或者,如果您愿意,可以使用"模板"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")
Run Code Online (Sandbox Code Playgroud)
这里,变量绑定来自第一个(模板)JSON,第二个来自值.模板JSON在宏扩展时解析,params
每次执行代码时都会解析JSON.
无论是否对你有用,我都不知道.
归档时间: |
|
查看次数: |
131 次 |
最近记录: |