使用Common Lisp进行开发时,我们有三种定义新setf形式的可能性:
我们可以定义一个函数,其名称是两个符号的列表,第一个是setf例如(defun (setf some-observable) (…)).
我们可以使用简短形式defsetf.
我们可以使用长形式defsetf.
我们可以用define-setf-expander.
我不确定每种可能性的正确或预期用例是什么.
对这个问题的回答可能会暗示最通用的解决方案和概述其他解决方案优越的背景.
define-setf-expander是这些中最普遍的.它的所有setf功能都包含在内.
定义setf函数适用于大多数访问器.使用泛型函数也是有效的,因此多态性不足以要求使用其他东西.控制评估的正确性或性能是不使用setf函数的主要原因.
为了正确,许多形式的解构都不可能与setf函数(例如(setf (values ...) ...)).类似地,我已经看到一个示例,通过更改(setf (dict-get key some-dict) 2)为新的字典分配,使功能数据结构在本地运行,就像一个可变的some-dict.
对于性能,考虑一个愚蠢的情况(incf (nth 10000 list)),如果nth编写器作为函数实现,则需要遍历10k列表节点两次,但在setf扩展器中可以通过单次遍历完成.