如何有效地设置结构(另一个结构)的单个字段?

How to set a single field of a structure (of another structure) efficently?

(cl-defstruct cache
  (owner (make-person))
  (folder (make-hash-table)))

(cl-defstruct person
  (name "")
  (phone ""))

(setq foo (make-cache))

(setf (cache-owner foo) (make-person :name "me" :phone "00000000"))
(let ((folder (cache-folder foo)))
  (puthash "/foo/" "20160201" folder)
  (puthash "/download/foo/" "20160101" folder)
  (setf (cache-folder foo) folder))

这是一个最小的例子。 在此示例中,缓存包含两个元素。一个是另一种结构,一个是散列table。这就是我当前更改单个元素的方式。

但是我觉得超级低效

首先,即使我只是想更改phone号码,我也需要创建一个新人。它适用于小型结构。但是,如果person是一个bulk结构体,除了name和phone之外还有很多其他的字段,那么开销会很大

我使用的另一种方法是创建一个局部变量来临时保存一个结构。然后它被写回到结构中。它看起来更好但仍然效率低下,因为它涉及复制整个结构并写回整个结构。

有没有更好的方法来完成这项工作?

First I need to make a new person even if I just want to change the phone number. It is fine for small structure. However, if person is a bulk structure with many other fields besides name and phone, there will be considerable overhead.

您不需要为了更改 phone 编号而创建新的 "person" 结构。您可以使用 setf:

更改它
(setf (person-phone p) "111111")

Another way I used is to create a local variable to hold a structure temporarily. Then it is written back to the structure. It seems better but still inefficient as it involves copying the whole structure and writing back the whole structure.

一般来说,除非您要求复制,否则在 Emacs Lisp 中不会复制任何内容。特别是,在上面的代码示例中,puthash 调用操作缓存结构中的散列 table,最后的 (setf (cache-folder foo) folder) 是多余的。