复制符号功能

时间:2017-02-23 00:40:18

标签: copy common-lisp symbols

Common Lisp提供了许多复制对象的功能;即copy-listcopy-alistcopy-seqcopy-structurecopy-treecopy-symbol。但是,copy-symbol似乎与其他人的运作方式略有不同。所有其他人(最值得注意的是copy-structure)都成功地采用了一般模式:

(setq riddle "gifted magician")  ;set some value for Tom Riddle
"gifted magician"
(setf (get 'riddle :school) "Hogwarts")  ;install a property for him
"Hogwarts"
(setq voldemort (copy-symbol 'riddle t))  ;attempt to clone him
#:RIDDLE
(get 'voldemort :school)  ;failed magic
NIL
  1. 我可以一次给伏地魔一切谜语(除了symbol-name除外),还是需要复制symbol-valuesymbol-plistsymbol-package,和谜语中的symbol-function分开? (HyperSpec提供了使用示例,但它们并未以新名称处理intern复制的符号。)

  2. copy-symbol通常用于什么(以及它可能用于什么)?

1 个答案:

答案 0 :(得分:2)

(setf (get symbol key) new-value)在符号对象上设置属性。因此,使用符号riddle的每个位置都是相同的符号,因此它将具有相同的属性列表。属性列表用于语言的实现方面,它不是制作对象的方法。早期的lisps用它来存储全球功能,全球价值,全球宏观。现代人对我们的关注很少,但它仍然是为了向后兼容。

(setq riddle "gifted magician")

这会更新已存在的变量riddle以与字符串“gifted magician”相关联

(setf (get 'riddle :school) "Hogwarts")

这与变量riddle(字符串“天才魔术师”)无关,但您在全局符号riddle上创建了一个属性。 CL使用属性列表来存储调试信息,而早期的lisps使用它作为全局范围。这不是创建对象的方法。

(setq voldemort (copy-symbol 'riddle t))

这使得带有属性列表的符号riddle的副本和符号值与voldemort相关联,因此:

voldemort               ; ==> riddle (looks the same, but is a copy)
(eq voldemort 'riddle)  ; ==> nil
(get voldemort :school) ; ==> "Hogwarts"

以下是使用classes and objects

执行此操作的方法
(defclass magician ()
  ((name        :initarg :name)
   (description :initarg :description :initform "")
   (school      :initarg :school :initform nil)))

(defparameter *riddle* 
  (make-instance 'magician :name        "Tom Riddle" 
                           :description "gifted magician")

(setf (slot-value *riddle* 'school) "Hogwarts")

; see http://stackoverflow.com/questions/11067899/is-there-a-generic-method-for-cloning-clos-objects
(defparameter *voldemort* (shallow-copy-object *riddle*))
(slot-value *voldemort* 'school)              ; ==> "Hogwarts"
(setf (slot-value *riddle* 'school) "Other")
(slot-value *voldemort* 'school)              ; ==> "Hogwarts"
(slot-value *riddle* 'school)                 ; ==> "Other"

如何使用structures

结构在场景之后做得更多,比如make访问器和构造函数,但它们不如CLOS类灵活,并且它们只有单继承。在示例中,它几乎可以正常工作。

(defstruct magician name (description "") (school nil))

(defparameter *riddle* (make-magician :name "Tom Riddle" 
                                      :description "Gifted magician"))
(setf (magician-school *riddle*) "Hogwarts")

(defparameter *voldemort* (copy-structure *riddle*))

(magician-school *voldemort*)              ; ==> "Hogwarts"
(setf (magician-school *riddle*) "Other")
(magician-school *voldemort*)              ; ==> "Hogwarts"
(magician-school *riddle*)                 ; ==> "Other"