gpt4 book ai didi

compilation - 评估-何时使用?

转载 作者:太空宇宙 更新时间:2023-11-03 18:33:35 29 4
gpt4 key购买 nike

在阅读了很多关于 Lisp eval-when 运算符的文档后,我仍然无法理解它的用途,我知道使用这个运算符我可以控制表达式的计算时间,但我做不到找出任何可能适用的示例?

最好的问候,utxee.

最佳答案

Lisp文件的编译

以Lisp文件的编译为例。 Lisp 编译器处理顶级形式。这些可以是任意的 Lisp 形式、DEFUN、DEFMACROS、DEFCLASS、函数调用……

文件编译器如何工作的整个故事太复杂了,无法在这里解释,但有几件事:

  • 文件编译器为 (DEFUN foo () ) 形式生成代码。但它不执行 defun 形式。这样在编译的时候就知道有一个函数FOO,但是在编译的时候就没有了ˋFOOˋ的代码。编译器为编译后的文件生成代码,但不将其保存在内存中。你不能在编译时调用这样的函数。

  • 对于宏,它的工作方式略有不同:(DEFMACRO BAZ ...)。文件编译器不仅会编译宏并注意它的存在,还会使宏在编译时可用。它被加载到编译器环境中。

想象一下文件中表单的顺序:

(defmacro baz ...)

(defun foo () (baz ...))

这是有效的,因为文件编译器知道宏 BAZ,当它编译 FOO 的代码时,它可以展开宏形式。

现在让我们看下面的例子:

(defun bar (form) ...)

(defmacro baz (form) (bar form))

(defun foo () (baz ...))

以上都行不通。现在宏 BAZ 通过调用函数 BAR 来使用它。当编译器试图编译函数 FOO 时,它不能扩展 BAZ 宏,因为不能调用 BAR,因为BAR 的代码未加载到编译时环境中。

有两种解决方法:

  1. 使用单独的文件编译加载BAR
  2. 使用EVAL-WHEN

EVAL-WHEN 示例:

 (eval-when (:compile-toplevel :execute :load-toplevel)
(defun bar (form) ...)
)

(defmacro baz (form) (bar form))

(defun foo () (baz ...))

现在 EVAL-WHEN 指示文件编译器在编译期间实际运行 DEFUN 形式。这样做的效果是:文件编译器现在在编译时 知道BAR 的定义。因此,当文件编译器需要在使用 BAZ 的宏扩展期间调用 BAR 时,它就可用了。

只能使用:compile-toplevel,当文件编译后不需要该函数时。如果稍后使用它,那么我们需要确保它被加载。

所以 EVAL-WHEN 允许指定是否应该运行一段特定的代码

  • 在文件编译期间
  • 在加载文件期间
  • 执行期间

EVAL-WHEN 在用户代码中并不经常使用。如果你使用它,那么你应该问问自己是否真的需要它。

关于compilation - 评估-何时使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10674650/

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