Common lisp (defun(setf…;)defsetf和define setf expander的典型用例是什么

Common lisp (defun(setf…;)defsetf和define setf expander的典型用例是什么,common-lisp,setf,Common Lisp,Setf,使用Common Lisp开发时,我们有三种可能定义新的setf-forms: 我们可以定义一个函数,其名称是两个符号的列表,第一个是setf,例如(defun(setf some observable)(…) 我们可以使用defsetf的缩写形式 我们可以使用长格式的defsetf 我们可以使用定义setf扩展器 我不确定这些可能性的正确或预期用例是什么 对这个问题的回答可能暗示最通用的解决方案,并概述其他解决方案优于的环境。define setf expander是其中最通用的。它包含了

使用Common Lisp开发时,我们有三种可能定义新的
setf
-forms:

  • 我们可以定义一个函数,其名称是两个符号的列表,第一个是
    setf
    ,例如
    (defun(setf some observable)(…)

  • 我们可以使用
    defsetf
    的缩写形式

  • 我们可以使用长格式的
    defsetf

  • 我们可以使用
    定义setf扩展器

我不确定这些可能性的正确或预期用例是什么


对这个问题的回答可能暗示最通用的解决方案,并概述其他解决方案优于的环境。

define setf expander
是其中最通用的。它包含了setf的所有功能

定义一个setf函数对大多数访问器都很好。使用泛型函数也是有效的,因此多态性不足以要求使用其他函数。控制正确性或性能的评估是不使用setf函数的主要原因

为确保正确性,许多形式的解构都不可能使用setf函数(例如,
(setf(值…)
)。类似地,我看到了一个示例,它通过更改
(setf(dict get key some dict)2)
某个dict
分配一个新字典,使函数数据结构在本地的行为类似于可变结构


性能,考虑<代码>(Inf(NTH 10000列表))/>代码>的愚蠢情况,如果将<代码> NT/<代码>编写为函数,则需要两次遍历10K列表节点,但在SETF扩展器中可以用一次遍历来完成。扩展器可用于解构(例如,

),并避免对同一事物进行两次计算,例如,如果您
incf
哈希表中的某个内容,则不需要对键进行两次散列/查找。“在开发包时”->setf表单与包无关。@RainerJoswig Fair.:-)这正是我想要的答案!谢谢