我正在开发一个将alist转换为查询参数的函数。到目前为止它看起来像这样。
(defun encode-options (opts)
"Turns an alist into url query parameters."
(format nil "~{~{~A=~A~}~^&~}" opts))
这适用于((a b) (c d))
之类的作品(导致"A=B&C=D"
),但对((a . b) (c . d))
等虚线列表失败。 (导致The value B is not of type LIST.
)
我的问题是: format
虚线列表是否有可能给我预期的结果以及如何?
答案 0 :(得分:6)
是否可以格式化虚线列表?
不,格式遍历正确的列表。
有许多可能的方法来实现您想要的。我在这里介绍其中两个。
(defun ensure-proper-list (value)
(typecase value
(null nil)
(cons (cons (car value)
(ensure-proper-list (cdr value))))
(t (list value))))
现在,您转换选项参数,以便所有元素都是正确的列表:
(defun encode-options (options)
"Turns an alist into url query parameters."
(format nil
"~{~{~A=~A~}~^&~}"
(mapcar #'ensure-proper-list options)))
(defun print-alist (stream data &optional colonp atsignp)
(declare (ignore colonp atsignp))
(destructuring-bind (head . tail) data
(format stream "~A=~A" head (if (consp tail) (first tail) tail))))
使用此新格式控件,按以下方式打印列表:
(defun encode-options (options)
"Turns an alist into url query parameters."
(format nil
"~{~/lib:print-alist/~^&~}"
options))
请注意,我添加了一个包前缀lib
,因为没有包,print-alist
会在用户包中找到(也就是COMMON-LISP-USER),在我看来很少是你的想。来自22.3.5.4 Tilde Slash: Call Function:
通过获取与〜/ name /指令对应的函数 查找指示中具有指示名称的符号 包。如果name不包含“:”或“::”,那么整个名称 在COMMON-LISP-USER包中查找字符串。
这就是为什么我建议总是提到带有~/
指令的包。