2016-09-26 69 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。