我明白,两者都用于临时更改函数的值。除了cl-flet
是一个函数,cl-letf
是一个宏,你什么时候使用它们呢?在emacs中,cl-flet和cl-letf有什么区别?
回答
的绑定可以递归
如果函数定义调用本身的名字,该函数将被调用? (比较cl-flet
与cl-labels
行为)。
作用域是词法...捕捉它们倒闭......
阅读有关词法绑定/范围VS动态绑定/范围。
cl-letf
可以用于设置动态绑定函数值,通过使用(symbol-function 'FUNC)
PLACE的某些FUNC。这与已弃用的flet
类似。
可以指定任何支持的PLACE,但对于函数绑定,cl-letf
不是只有。
你什么时候使用它们?
当您想临时定义(或覆盖)一个函数。您对任何给定用例所需的范围规则将决定您将使用哪个选项。
(cl-flet ((FUNC ARGLIST BODY...) ...) FORM...)
FUNC是可见的只是形式上的代码。
(cl-labels ((FUNC ARGLIST BODY...) ...) FORM...)
FUNC可见既在形式代码,并在FUNC自己的身体的代码。直到身体已经完成正在评估
(cl-letf (((symbol-function 'FUNC) VALUE) ...) BODY...)
FUNC是可见的绝对一切。
一些(相当做作)的例子......
在第一个例子中,我们定义的临时功能递归 - 它自称 - 因此我们使用cl-labels
:
(nb这不是一个强大的析因实现;它仅用于演示目的。)
(defun my-factorial (number)
"Show the factorial of the argument."
(interactive "nFactorial of: ")
(cl-labels ((factorial (n) (if (eq n 1)
1
(* n (factorial (1- n))))))
(message "Factorial of %d is %d" number (factorial number))))
如果更改cl-labels
到cl-flet
你只要内(factorial (1- n))
评估得到一个错误,因为内我们暂时的功能,无功能factorial
是已知的。
如果你是再定义一个全局factorial
功能无条件地返回值1
:
(defun factorial (n) 1)
然后通过cl-flet
定义的factorial
功能会看到是当它调用factorial
,并my-factorial
会计算(* n 1)
作为任何参数的值n
。
当不需要递归,cl-flet
是蛮好用的:
(defun my-square (number)
"Show the square of the argument."
(interactive "nSquare of: ")
(cl-flet ((square (n) (* n n)))
(message "Square of %d is %d" number (square number))))
两个cl-labels
和cl-flet
提供词法范围的功能,唯一可见这些宏调用的机构内编写的代码;并且特别是而不是的任何其他功能的代码,我们可能是,调用。
如果你正在定义一个辅助函数,比如上面的例子,词法作用域可能就是你想要的,因为你有一个合理的机会只能在宏体内调用你的帮助器。
但是,如果您正试图暂时将覆盖这个现有的函数,那么您将需要调用的函数来查看覆盖。在这种情况下,您需要重写动态范围。
在过去flet
是提供临时功能动态范围的方式,但flet
现在已不倾向于使用cl-letf
用的(symbol-function 'FUNC)
在下面的例子“地方”的,则乘法函数被重写,动态范围意味着my-square
和my-factorial
将会看到并使用我们对乘法的临时定义。
(defun my-bad-square()
"Maths gone wrong."
(interactive)
(cl-letf (((symbol-function '*) '+))
(call-interactively 'my-square)))
(defun my-bad-factorial()
"More maths gone wrong."
(interactive)
(cl-letf (((symbol-function '*)
(lambda (x y) (- x y))))
(call-interactively 'my-factorial)))
您能否指出我在PLACE定义的文档部分?从cl-letf的文档中我不清楚,我可以用作PLACE的具体用途。 – UndeadKernel
从'C-h i g(elisp)通用变量'开始,然后阅读'设置通用变量'节点。 – phils
- 1. 在Lisp(Clojure,Emacs Lisp)中,list和quote有什么区别?
- 2. 有什么区别`和$(Bash中有什么区别?
- 3. emacs中'M-x load-file'和'M-x load-library'有什么区别?
- 4. emacs中的“abort”和“terminate-thread”有什么区别?
- 5. emacs中setq和set-variable有什么区别?
- 6. 在JavaScript中,'\'和'\ n'有什么区别?
- 7. =和在mysql中有什么区别?
- 8. 在Ember.js中,[]和Ember.A([])有什么区别?
- 9. 在PHP中!==和!=有什么区别?
- 10. *和。*在matlab中有什么区别?
- 11. !=和=!有什么区别!在Java中?
- 12. &&和||有什么区别?在JavaScript中?
- 13. 在Prolog中==和= =有什么区别?
- 14. 〜/和〜在linux中有什么区别?
- 15. ==和===有什么区别?
- 16. ==和===有什么区别?
- 17. 有什么区别? :和||
- 18. ==和===有什么区别?
- 19. '=='和'==='有什么区别?
- 20. `&`和`ref`有什么区别?
- 21. 有什么区别:。!和:r!?
- 22. | 0和~~有什么区别?
- 23. Appender和〜有什么区别?
- 24. emacs中shell和eshell的区别是什么?
- 25. xtype和别名有什么区别?
- 26. 别名和标签有什么区别? (一般和在git中)
- 27. 在Purescript; - >和=>有什么区别?
- 28. 有什么区别&和@在SASS
- 29. 有什么区别使用=和:在javascript
- 30. 有什么区别?和*在Bash?
这是什么'C-H F'告诉你吗? ** CL **手册('C-h i m cl')的节点**功能绑定**和**修改宏**告诉你什么? – Drew
当然我已经检查过手册。我已阅读了关于这些功能的所有信息。恐怕我无法理解文档的内容。例如,对于'cl-flet':“创建临时函数绑定。绑定可以是递归的,并且范围是词法,但是在闭包中捕获它们只会在使用'词法绑定'的情况下起作用。武汉理工大学? – UndeadKernel
有时需要更多的阅读(例如,在这种情况下,如果你不熟悉词汇绑定的话)。但是,如果您发现某些您认为错误或从文档中遗漏的内容,请考虑报告它,以便可以改进:'M-x report-emacs-bug'。应该在文档中详细说明使用'cl-flet'和表面上看起来类似的功能。 – Drew