来自 plist 的 Common Lisp remf 指示器不起作用

Common Lisp remf indicator from plist not working

我有一个名为 use 的函数,它接受任意数量的关键字参数(作为 plist),定义如下:

(defun use (&rest plist &key &allow-other-keys)
  ":href should be supplied, as it is the path/to/svg#id to be used."
  ;; Hole die Sachen die wichtig sind aus der PListe
    (let ((href (getf plist :href "#")))
      ;; Remove :href otherwise it appears in the plist again!
      (remf-indicators-from-plist '(:href) plist)
      (list plist href)
    ))

在这里我提取了一些重要的并且应该由用户指定的关键字参数,然后使用remf-indicators-from-plist从提供的关键字参数的plist中删除它们,这样我就不会处理它们两次. remf-indicators-from-plist定义如下:

(defun remf-indicators-from-plist (indicators plist)
  "Removes indicators from the plist, 
to prevent callers from double-using them."
  (dolist (indicator indicators plist)
    (remf plist indicator)))

现在在我看来,如果关键字 argument/s 我想在 use 函数中提取然后删除,如果它们不是作为函数的第一个参数出现的话,确实会被删除:

(use :x 34 :href 23 :c2 32)     ;((:X 34 :C2 32) 23)
(use :x 34 :c2 32 :href 23)     ;((:X 34 :C2 32) 23)

但如果它作为第一个参数出现则不会:

(use :href 23 :x 34 :c2 32)     ;((:HREF 23 :X 34 :C2 32) 23)

这是为什么?我怎样才能正确实施它?

问题出在函数 use 中,而 remf-indicators-from-plist 可以正常工作。

原因是函数remf-indicators-from-plistreturns修改了列表(在dolist内),但返回的值在use内被丢弃。一种可能的解决方案是将 use 的定义更改为例如:

CL-USER> (defun use (&rest plist &key &allow-other-keys)
            ":href should be supplied, as it is the path/to/svg#id to be used."
            ;; Hole die Sachen die wichtig sind aus der PListe
          (let ((href (getf plist :href "#"))
                (new-plist (remf-indicators-from-plist '(:href) plist)))
            (list new-plist href)))
USE
CL-USER> (use :x 34 :href 23 :c2 32)  
((:X 34 :C2 32) 23)
CL-USER> (use :href 23 :x 34 :c2 32) 
((:X 34 :C2 32) 23)

事实上,当 :href 在 plist 中时,一切显然都有效,这是由于 Common Lisp 中某些操作执行副作用的特殊方式。有助于管理副作用操作的规则(部分原因是永远不应修改常量数据这一事实)如下:始终 returns 被修改的结构,即使修改似乎发生在“适当的位置” ”。