2

我的目标是获取一个 alist(alist 是传递给 Drakma 的“参数”参数的那个;但这对于这个问题并不重要)并将其序列化为某种形式的字符串(在这种情况下,一个 HTTP 参数字符串)。

所以让我们来看看这个清单:

    (list (cons 1 2) (cons 3 4) (cons 5 6))

然后我想要的是最终得到一个格式如下的字符串:

    "?1=2&3=4&5=6"

到目前为止我所做的是:

    (defvar *s* 
      (make-array 0 
              :element-type 'character 
              :adjustable t 
              :fill-pointer 0))

    ;; (serialize-params) will return a properly formatted string 
    ;; that will be used elsewhere in another function
    (defun serialize-params (params)
      (loop for (a . b) in params
         do (format *s* "~a=~a&" a b))
      (concatenate 'string "?" (trim *s*)))

    ;; Utility function to remove the last character of a string
    (defun trim (str)
      (subseq str 0 (- (length str) 1)))

它有点工作,但我真的不喜欢这个有几个原因:

  • 我不想使用特殊变量
  • 每次我运行(serialize-params (...))时,*s*只需附加到上一个调用

我认为要解决我的问题,我必须以loop某种特殊的方式使用,并且可能必须在我的函数中绑定一个词法变量。问题是我不确定如何将每次迭代附加(format nil "...")到该词法变量...

免责声明:我是 lisp 的新手。

4

1 回答 1

1

with-output-to-string 似乎很适合您的问题。它创建了一个你可以在循环中写入的流,并将你写的任何内容作为字符串返回:

(with-output-to-string (s)
   (loop with first = t
         for (a . b) in params
         if first 
           do (setq first nil)
              (princ "?" s)
         else
           do (princ "&" s)
         end
         do (format s "~a=~a" a b)))
于 2014-03-21T14:22:36.577 回答