我知道两者都用于临时更改函数的值.除了这cl-flet是一个功能并且cl-letf是一个宏的事实,你什么时候使用它们?
phi*_*ils 11
绑定可以是递归的
如果函数定义按名称调用自身,将调用哪个函数?(比较cl-flet与cl-labels行为).
范围是词汇......在封闭中捕获它们......
阅读有关词法绑定/范围与动态绑定/范围的信息.
cl-letf可以通过对某些FUNC 使用PLACE 来设置动态绑定的函数值(symbol-function 'FUNC).这与已弃用的类似flet.
但是,可以指定任何支持的PLACE - cl-letf不仅适用于功能绑定.
你什么时候使用它们?
当您想要临时定义(或覆盖)函数时.您对任何给定用例所需的范围规则将决定您将使用哪个选项.
(cl-flet ((FUNC ARGLIST BODY...) ...) FORM...)
FUNC仅对FORM中的代码可见.
(cl-labels ((FUNC ARGLIST BODY...) ...) FORM...)
FUNC对FORM中的代码和FUNC自己的BODY中的代码都可见.
(cl-letf (((symbol-function 'FUNC) VALUE) ...) BODY...)
在BODY完成评估之前,FUNC对于绝对一切都是可见的.
一些(相当人为的)例子......
在第一个例子中,我们定义的临时函数是递归的 - 它调用自身 - 因此我们使用cl-labels:
(这不是一个强大的阶乘实现;它仅用于演示目的.)
(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))))
Run Code Online (Sandbox Code Playgroud)
如果你改变cl-labels对cl-flet你会尽快内得到一个错误(factorial (1- n))的评估,因为内我们暂时功能,无功能factorial而着称.
如果您要定义一个factorial无条件返回值的全局函数1:
(defun factorial (n) 1)
Run Code Online (Sandbox Code Playgroud)
然后,factorial通过定义的函数cl-flet将看到的是当它调用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))))
Run Code Online (Sandbox Code Playgroud)
双方cl-labels并cl-flet提供词法范围的功能,可见只有那些宏调用的机构内编写的代码; 并且特别是不给的,我们也可以任何其他函数的代码调用.
如果你正在定义一个辅助函数,例如上面的例子中,词法作用域可能就是你想要的,因为你有可能只在宏体内调用你的助手.
但是,如果您试图临时覆盖现有函数,那么您很可能需要使用您正在调用的函数来查看覆盖.在这种情况下,您需要覆盖以具有动态范围.
过去flet是为临时函数提供动态范围的方法,但flet现在不赞成使用cl-letf'place'(symbol-function 'FUNC)
在下面的示例中,乘法函数被重写,动态范围意味着my-square并且my-factorial将查看并使用我们的乘法的临时定义.
(defun my-bad-square ()
"Maths gone wrong."
(interactive)
(cl-letf (((symbol-function '*) '+))
(call-interactively 'my-square)))
Run Code Online (Sandbox Code Playgroud)
(defun my-bad-factorial ()
"More maths gone wrong."
(interactive)
(cl-letf (((symbol-function '*)
(lambda (x y) (- x y))))
(call-interactively 'my-factorial)))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
866 次 |
| 最近记录: |