Peter Norvig在第 50 页的《人工智能编程范式》中提到,在选择使用 setq 或 setf 将变量更新为值时,需要权衡特异性和一致性之间的关系。你有什么建议吗?你有没有遇到过比可读性更重要的情况?
6 回答
使用 setq 比较底层,但是 setf 的性能没有问题。setf 允许您(或库编写者)提供自定义 setf 行为,例如设置自定义数据结构的一部分。我说:除非你有理由不这样做,否则随处使用 setf。
另请参阅 Practical Common Lisp,第 3 章:“SETF 宏是 Common Lisp 的主要赋值运算符。” PCL 可免费在线获取:http: //gigamonkeys.com/book/
FWIW,我总是使用setf
. 如果我稍微改变我的代码结构,我只需要改变“地点”而不是地点和运算符(setq -> setf)。
另外,不用担心性能, setf 与符号的 setq 完全相同:
CL-USER> (macroexpand '(setf foo 42))
(SETQ FOO 42)
您可以在任何可以使用的setf
地方使用setq
. 实际上, setf
实际上是一个建立在setq
. 所以,这应该纯粹是一个可读性和风格问题。
我见过的几乎所有代码都避免使用setq
和使用setf
.
setf 是“设置字段”,它改变了一个地方并且可以有用户扩展。setq 设置为引用第一个参数。
我建议您遵循 Norvig 在该部分中的最终建议:保持一致。“可读性”当然是在编程中做出任何选择的最重要原因。如果向读者(可能在 2 个月后)传达您正在处理符号的整个值单元格很重要,请使用setq
; 否则使用setf
. 但前提是你保持一致。
如果你到处使用 setf 而不是 setq,你就不会错。
正是这样的事情拖累了 Common Lisp 的发展,许多未使用的东西仍然需要实现者支持。