2016-09-26 102 views
3
(defclass schedule() 
    ((day :accessor schedule-day :initarg :day))) 
(setf october 
    (make-array '(31) 
     :element-type 'schedule 
     :initial-element 
     (make-instance 'schedule :day 0))) 
(setq searcher (read)) 
(setf (schedule-day (aref october (- searcher 1))) searcher) 

(dotimes (i 31) 
    (format t "-month:10 day:~S~%" (schedule-day (aref october i)))) 

這是我10月的計劃程序的一部分。 這部分應該在我打字的那一天,改變那天的元素,並打印每個十月的時間表。無法修改對象數組中的特定元素

然而,

(setq searcher (read)) 
(setf (schedule-day (aref october (- searcher 1))) searcher) 

我有這個煩惱。如果我輸入17,那麼只有october 17日應該受到影響,印像這樣,

-month:10 day:0 
-month:10 day:0 
... 
-month:10 day:17 
-month:10 day:0  
... 

但是我真正得到的是

-month:10 day:17 
-month:10 day:17 
-month:10 day:17 
... 

爲什麼我不能只有一個元素改變?我能夠做到這一點類似於C++,

october[searcher - 1].setDay(searcher); 

看來setf影響了類本身,而不是類對象。你可以幫我嗎?謝謝。

+0

請修復parens和indentation。您的代碼現在無法閱讀。 – sds

+0

我認爲現在可以嗎?它只是一個類和一個make-array:p – user3026854

+0

如果提供了初始元素,它將用於初始化新數組中的每個元素(使用與你相同的對象) – FrankS101

回答

6

你的問題是你的數組包含31個指針,每個指針指向同一個對象。

因此(setf (schedule-day (aref october a)) b)修改該唯一對象。

你可以達到你想要的東西通過兩種封裝october使得i個元素只在必要時,或通過初始化的東西數組一樣

(apply #'vector (loop repeat 31 collect (make-instance 'schedule))) 

(make-array 31 :initial-contents (loop repeat 31 collect (make-instance 'schedule))) 

的創建你的困惑的根本原因是你指定了數組元素類型並假定你創建了一個"specialized" array。 因此,儘管你實際上只需要調用(make-instance 'schedule)一次,你將在連續的內存中擁有31個對象。 然而,你的實現是有義務兌現 元素型規格在方式(這將創建 可以抱你指定類型的對象的數組,但不一定 只有這些對象), 和你實際得到的是一個simple-vector

PS。你應該 使用defvar or defparameter 代替setqsetf定義全局變量 (如october),你應該使用 "earmuffs", 像*october*他們的名字 。

+0

對不起,我想我幾乎可以得到它但考慮我作爲一個嚴肅的noob;我如何訪問你的代碼所做的向量?我試過(setf october(vector blah blah)),我想我做錯了... – user3026854

+0

請看編輯 – sds

+0

非常感謝!你是一個拯救生命的人!哦,並在:初始內容你的意思是:初始內容? – user3026854

4

您可以很容易地看到數組元素只指向一個CLOS對象。

CL-USER 28 > (defclass foo()()) 
#<STANDARD-CLASS FOO 4020002613> 

CL-USER 29 > (make-array 3 :initial-element (make-instance 'foo)) 
#(#<FOO 402000AE9B> #<FOO 402000AE9B> #<FOO 402000AE9B>) 

所有對象都有相同的ID 402000AE9B

在下面的例子中的對象是不同的:

CL-USER 30 > (make-array 3 :initial-contents (list (make-instance 'foo) 
                (make-instance 'foo) 
                (make-instance 'foo))) 
#(#<FOO 4020000B43> #<FOO 4020000B63> #<FOO 4020000B83>) 

所有具有不同的ID。