2016-02-09 41 views
0
(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)) 

這是一個簡單的例子。 在這個例子中,緩存包含兩個元素。一個是另一個結構,一個是散列表。這是我如何改變當前的個人元素。如何有效地設置(另一個結構的)結構的單個字段?

但是,我覺得它是超效率的。

首先,即使我只想更改電話號碼,我也需要創建一個新人。小結構很好。但是,如果人員是除名稱和電話以外的許多其他領域的散裝結構,則會產生相當大的開銷。

我使用的另一種方法是創建一個局部變量來暫時保存結構。然後它被寫回結構。這似乎更好,但仍然效率低下,因爲它涉及複製整個結構並回寫整個結構。

有沒有更好的方法來完成這項工作?

回答

1

首先我需要做一個新的人,即使我只是想改變電話號碼。小結構很好。但是,如果人員是除名稱和電話以外的許多其他領域的散裝結構,則會產生相當大的開銷。

您不需要創建新的「人員」結構來更改電話號碼。你可以用setf更改:

(setf (person-phone p) "111111") 

我用另一種方式是創建一個局部變量來臨時存放的結構。然後它被寫回結構。這似乎更好,但仍然效率低下,因爲它涉及複製整個結構並回寫整個結構。

一般來說,在Emacs Lisp中,除非您要求將其複製,否則不會複製任何內容。特別是,在上面的代碼示例中,puthash調用操作緩存結構中的哈希表,最後的(setf (cache-folder foo) folder)是多餘的。

+0

但是用'let'創建局部變量。 '文件夾'應該是哈希表的本地副本。我錯過了什麼嗎? – tom

+0

是的,如果你想要一個散列表的副本,你需要使用'copy-hash-table'。否則,您只需獲取對原始哈希表的引用。 – legoscia

+0

任何方式來simipified'(setf(人電話(緩存擁有者foo))「111111」)'如果我需要設置富人的多個領域? – tom

相關問題