读:The Many Faces of flet——Elisp 局部函数的三种写法
💡
原文中文,约3600字,阅读约需9分钟。
📝
内容提要
本文介绍了 Elisp 中局部函数的三种写法:cl-flet、cl-labels 和 cl-letf。cl-flet 用于定义局部辅助函数,cl-labels 支持递归,cl-letf 用于临时覆盖全局函数。旧的 flet 已被废弃,因其在词法作用域下行为不可预测。选择合适的宏需根据具体需求。
🎯
关键要点
- 旧的 flet 被废弃,因其在词法作用域下行为不可预测。
- cl-flet 用于定义局部辅助函数,绑定是词法作用域,其他函数看不到这个覆盖。
- cl-labels 支持递归,函数在自己的定义体内可见,适合需要递归的场景。
- cl-letf 用于临时覆盖全局函数,直接修改函数的 function cell,所有调用路径都会看到替换。
- 选择合适的宏需根据具体需求:日常使用 cl-flet,递归使用 cl-labels,测试中需要 stub 全局函数使用 cl-letf。
❓
延伸问答
为什么旧的 flet 被废弃?
旧的 flet 在词法作用域下行为不可预测,导致其被废弃。
cl-flet 和 cl-labels 有什么区别?
cl-flet 仅在其定义体内可见,不支持递归,而 cl-labels 支持递归,函数在自己的定义体内可见。
如何使用 cl-letf 来覆盖全局函数?
使用 cl-letf 可以通过修改函数的 function cell 来临时覆盖全局函数,退出时会自动恢复原始定义。
在什么情况下应该使用 cl-labels?
当需要递归或互递归的局部函数时,应使用 cl-labels。
cl-flet 的作用是什么?
cl-flet 用于定义局部辅助函数,其绑定是词法作用域,其他函数看不到这个覆盖。
使用 cl-letf 时需要注意什么?
使用 cl-letf 时要小心,因为它直接修改全局函数槽,可能影响所有调用路径。
➡️