Я развернул макрос ниже, чтобы увидеть, как он работает, и нашел себя немного смущенным.Понимание расширения макросов цикла
(loop for i below 4 collect i)
расширяется (я прибрал ее немного для удобства чтения)
(block nil
(let ((i 0))
(declare (type (and number real) i))
(let* ((list-head (list nil))
(list-tail list-head))
(tagbody
sb-loop::next-loop
(when (>= i 4) (go sb-loop::end-loop))
(rplacd list-tail (setq list-tail (list i)))
(setq i (1+ i))
(print "-------") ;; added so I could see the lists grow
(print list-head)
(print list-tail)
(print "-------")
(go sb-loop::next-loop)
sb-loop::end-loop
(return-from nil (cdr list-head))))))
..и здесь есть выход из работы выше ..
;; "-------"
;; (NIL 0)
;; (0)
;; "-------"
;; "-------"
;; (NIL 0 1)
;; (1)
;; "-------"
;; "-------"
;; (NIL 0 1 2)
;; (2)
;; "-------"
;; "-------"
;; (NIL 0 1 2 3)
;; (3)
;; "-------"
Я просто не могу 't видеть, где изменен список, я должен предположить, что голова и хвост - это eq
, и, таким образом, изменение одного из них изменило другое, но кто-то может сломать то, что происходит на линии rplacd
е?
Почему вы хотите изменить список? См. Это как один связанный список: голова не изменяется, только хвост, когда вы добавляете новый элемент. Тем не менее, функция 'print', применяемая в списке, печатает список из текущего элемента в последний элемент, поэтому вы видите рост списка и изменение списка. – Bentoy13
Я не хочу, чтобы это было изменено. Я хочу понять, что на самом деле происходит. Если вывод на печать затрудняет ситуацию, возможно, поэтому я не понимаю. Вы должны оставить свой комментарий в ответе, чтобы я мог послать вам карму! – Baggers
+1 для хорошего вопроса, который врывается в исходный код, использует макрорасширение, показывает четкое поведение, о котором возникает вопрос и т. Д. Приятно! –