Lisp 如何从plist获取属性

Lisp 如何从plist获取属性,lisp,common-lisp,string-to-symbol,Lisp,Common Lisp,String To Symbol,我是口齿不清的新手。 我想使用如下字符串变量从属性列表访问特定属性 (setf sym (list :p1 1)) (setf x "p1") (getf sym :x) getf的第二个参数是一个关键字,您有一个字符串。关键字是存在于包关键字中的符号,通常由读取器大写: ? (setf sym (list :p1 1)) (:P1 1) ? sym (:P1 1) 因此,您需要使用: ? (getf sym (find-symbol (string-upcase x) "KEYWORD")

我是口齿不清的新手。 我想使用如下字符串变量从属性列表访问特定属性

(setf sym (list :p1 1))
(setf x "p1")
(getf sym :x)

getf
的第二个参数是一个关键字,您有一个字符串。关键字是存在于包关键字中的符号,通常由读取器大写:

? (setf sym (list :p1 1))
(:P1 1)
? sym
(:P1 1)
因此,您需要使用:

? (getf sym (find-symbol (string-upcase x) "KEYWORD"))
1
关于cl:getf 让小王子的答案是正确的,这可能是你想在这里使用的功能,但请注意,它可以用于不仅仅是关键字符号。您可以将其用于任何对象。属性列表只是交替指示符和值的列表,任何对象都可以是指示符:

(let ((plist (list 'a 'b 'c 'd)))
  (getf plist 'c))
;=> D
您甚至可以使用字符串作为指示符:

(let* ((name "p1")
       (plist (list name 1)))
  (getf plist name))
;=> 1
然而,这可能不是很好的实践,因为getf将指标与eq进行比较。这意味着使用字符串作为指示符可能不可靠,具体取决于您的用例:

(let ((plist (list "p1" 1)))
  (getf plist "p1"))
;=> NIL
以你为例 在您的例子中,您试图获取一个字符串,并为一个名称为字符串相等(即,具有相同的字符,但不考虑大小写)的符号查找对象。在列表上循环并将指标与字符串相等进行比较可能更有意义

(let ((plist '(:p1 1 :p2 2)))
  (loop 
     for (indicator value) on plist by #'cddr
     when (string-equal indicator "p1")
     return value))
;=> 1
当然,您可以将其封装在函数中进行抽象:

(defun getf-string-equal (plist indicator)
  (loop
     for (i v) on plist by #'cddr
     when (string-equal i indicator)
     return v))


getf的第二个参数不一定是关键字。这是任何物体。关键字符号通常是关键字,但也有一个很好的例子可以让它们成为其他软件包中的非关键字符号:指示器冲突的可能性较小。@JoshuaTaylor:因为相同的数字和字符不需要相同,所以GETF可能对那些没有用的…@RainerJoswig没错,我在回答中给出了一些例子。GETF在那里并不有用,但对于非关键字符号仍然非常有用。
(getf-string-equal '(:p1 1 :p2 2) "p1")
;=> 1