gpt4 book ai didi

emacs - 在emacs中,cl-flet和cl-letf有什么区别?

转载 作者:行者123 更新时间:2023-12-04 16:58:36 25 4
gpt4 key购买 nike

我知道两者都用于临时更改函数的值。除了cl-flet是一个函数,cl-letf是一个宏,你什么时候使用它们?

最佳答案

The bindings can be recursive



如果函数定义通过名称调用自身,会调用哪个函数? (比较 cl-fletcl-labels 行为)。

Scoping is lexical ... capturing them in closures ...



阅读有关词法绑定(bind)/范围与动态绑定(bind)/范围的信息。
cl-letf可用于设置动态绑定(bind)的函数值,通过使用 PLACE (symbol-function 'FUNC)对于一些 FUNC。这类似于已弃用的 flet .

但是,可以指定任何受支持的 PLACE -- cl-letf不仅适用于函数绑定(bind)。

when do you use them?



当您想临时定义(或覆盖)一个函数时。您对任何给定用例所需的范围规则将决定您将使用哪个选项。

  • (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))))

    如果您更改 cl-labelscl-flet一旦内部 (factorial (1- n)) 出现,您将收到错误消息。被评估,因为在我们的临时函数中,没有函数 factorial是已知的。

    如果您要定义一个全局 factorial无条件返回值 1 的函数:

    (defun factorial (n) 1)

    然后 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))))

    两个 cl-labelscl-flet提供词法范围的函数,仅对那些宏调用的主体中编写的代码可见;尤其是我们可能调用的任何其他函数的代码。

    如果您在上面的示例中定义一个辅助函数,那么词法作用域可能就是您想要的,因为您很有可能只在宏体内调用您的辅助函数。

    但是,如果您尝试临时覆盖现有函数,则很有可能您需要调用的函数才能看到覆盖。在这种情况下,您需要覆盖具有动态范围。

    过去 flet是为临时函数提供动态范围的方法,但是 flet现在不赞成使用 cl-letf “地点”为 (symbol-function 'FUNC)
    在以下示例中,乘法函数被覆盖,动态范围意味着 my-squaremy-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)))

    关于emacs - 在emacs中,cl-flet和cl-letf有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39550578/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com