use*_*854 3 lisp arrays common-lisp
(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))))
Run Code Online (Sandbox Code Playgroud)
这是我的十月调度计划的一部分.这部分应该是我输入的那一天并更改当天的元素,并打印每个十月的时间表.
然而,
(setq searcher (read))
(setf (schedule-day (aref october (- searcher 1))) searcher)
Run Code Online (Sandbox Code Playgroud)
我在这方面遇到麻烦.如果我输入17,那么只有第17天会october受到影响并打印出来,
-month:10 day:0
-month:10 day:0
...
-month:10 day:17
-month:10 day:0
...
Run Code Online (Sandbox Code Playgroud)
但我真正得到的是
-month:10 day:17
-month:10 day:17
-month:10 day:17
...
Run Code Online (Sandbox Code Playgroud)
为什么我不能只改变一个元素?我设法在c ++中这样做,
october[searcher - 1].setDay(searcher);
Run Code Online (Sandbox Code Playgroud)
它似乎setf影响了类本身,而不是类对象.你能帮助我吗?谢谢.
您的问题是您的数组包含31个指针,每个指针指向同一个对象.
因此(setf (schedule-day (aref october a)) b)修改了该唯一对象.
您可以通过封装来实现所需的目的,october以便i仅在必要时创建th元素,或者通过使用类似的东西初始化数组
(apply #'vector (loop repeat 31 collect (make-instance 'schedule)))
Run Code Online (Sandbox Code Playgroud)
要么
(make-array 31 :initial-contents (loop repeat 31 collect (make-instance 'schedule)))
Run Code Online (Sandbox Code Playgroud)
您混淆的根本原因是您指定了数组元素类型并假设您创建了一个"专用"数组.因此,尽管您实际上(make-instance 'schedule)只调用一次,但在连续的内存中将有31个对象.但是,您的实现没有义务以这种方式遵守元素类型规范(它将创建一个可以保存您指定类型的对象的数组,但不一定
只包含那些对象),而您实际获得的是a simple-vector.
PS.你应该使用defvar或defparameter
代替setq
或setf定义全局变量(比如october),你应该使用"耳罩"来命名它们
,比如*october*.
| 归档时间: |
|
| 查看次数: |
59 次 |
| 最近记录: |