理解Common Lisp的aref行为

4
我不明白为什么setf不能与从函数调用返回的数组引用一起使用。在下面的例子中,为什么最后一次调用会失败?
(setf arr #1a(a b c))

(defun ret-aref (a i)
    (aref a i))

(eql (ret-aref arr 0) (aref arr 0))

;succeeds
(progn
    (setf (aref arr 0) 'foo)
    arr)

;fails
(progn
    (setf (ret-aref arr 0) 'bar)
    arr)
1个回答

9
setf 操作符实际上是一个宏,需要在编译时检查 place-form。它对 aref 有特殊的了解,但对你的 ret-aref 一无所知。
使你的函数被 setf 认可的最简单方法是为其定义一个适当的 setf 函数伴随体。例如:
(defun (setf ret-aref) (new-value array index) 
   (setf (aref array index) new-value))

现在, (setf (ret-aref arr 0) 'bar) 应该可以工作了。
这个简单的例子隐藏了一个事实,即setf扩展实际上是一个相当复杂的主题。你可以在CLHS中找到所有细节

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接