Cố gắng hiểu những gì setfcó thể làm, tôi gọi
(macroexpand '(setf (aref vec i) val))
⇒ (let* ((v vec) (v i)) (aset v v val))
Điều này rõ ràng là sai.
Tuy nhiên tôi không thể tạo ra một ví dụ thực tế khi (setf (aref ..thất bại. Ví dụ
(setq vec (make-vector 10 nil) i 3 val 'foo)
⇒ foo
(setf (aref vec i) val)
⇒ foo
vec
⇒ [nil nil nil foo nil nil nil nil nil nil]
Ai đó có thể giải thích những gì đang xảy ra ở đây?
Kỳ lạ thay, các mã cho
—
PHS
setftrong tập tin nguồn gv.eldường như để tạo ra các vbiểu tượng với một sử dụng vani của (gensym "v")và điều này nên nối thêm một giá trị truy cập sau "v" tiền tố, tạo ra những biểu tượng uninterned v0, v1, v2vv
Bạn có thể muốn chơi với
—
Stefan
print-gensymđể thấy rõ hơn những gì đang diễn ra.
@stefan: Tôi có emacs-26.1 và nó không có
—
phs
print-gensymAFAICT :-( Có ai có lời giải thích tại sao (gensym "v")tệp trong nguồn gv.elkhông xuất hiện không gensym-counter?!
Tôi khá chắc chắn rằng bạn có
—
Stefan
print-gensym, bạn có thể chỉ nhìn nhầm chỗ (thử C-h othay vì C-h f). Các let*trong mã mở rộng của bạn có khả năng tạo ra bởi macroexp-let2đó sử dụng make-symbolchứ không phải là gensym.
vbiểu tượng không giống nhau và(let* ((form (macroexpand '(setf (aref vec i) val))) (symb1 (caar (cadr form))) (symb2 (caar (cdadr form)))) (equal symb1 symb2))trả vềnil.