Оценка во время компиляции
Эти возможности позволяют вам писать код, который будет оцениваться во время компиляции программы.
- Макрос: eval-and-compile body…
Эта форма отмечает body для оценки как при компиляции содержащего его кода, так и при его выполнении (вне зависимости от того, компилируется оно или нет).
Вы можете получить похожий результат, поместив body в отдельный файл и сделав ссылку на этот файл с помощью
require. Этот метод предпочтительнее, когда body большой. По сути,requireавтоматическиeval-and-compile, пакет загружается как при компиляции, так и при выполнении.autoloadтакже эффективноeval-and-compile. Он распознается при компиляции, поэтому использование такой функции не приводит к предупреждениям «неизвестно, определена ли».Большинство случаев использования
eval-and-compileдовольно сложные.Если макрос имеет вспомогательную функцию для построения своего результата, и этот макрос используется как локально, так и вне пакета, то следует использовать
eval-and-compile, чтобы получить вспомогательную функцию как при компиляции, так и при последующем выполнении.Если функции определены программно (скажем, с помощью
fset), тоeval-and-compileможет быть использовано для того, чтобы это было сделано во время компиляции, а также во время выполнения, поэтому вызовы этих функций проверяются (и подавляются предупреждения о «неизвестно, определена ли»).
- Макрос: eval-when-compile body…
Эта форма отмечает body для оценки во время компиляции, но не при загрузке скомпилированной программы. Результат оценки компилятором становится константой, которая появляется в скомпилированной программе. Если вы загружаете исходный файл вместо его компиляции, body оценивается обычным образом.
Если вам нужна константа, для создания которой требуется вычисление,
eval-when-compileможет выполнить это во время компиляции. Например,(defvar my-regexp (eval-when-compile (regexp-opt '("aaa" "aba" "abb"))))Если вы используете другой пакет, но вам нужны только макросы из него (байткодовый компилятор расширит их), то
eval-when-compileможет быть использовано для загрузки его для компиляции, но не для выполнения. Например,(eval-when-compile (require 'my-macro-package))
То же самое относится к макросам и
defsubstфункциям, определенным локально и предназначенным только для использования в пределах файла. Они необходимы для компиляции файла, но в большинстве случаев они не нужны для выполнения скомпилированного файла. Например,(eval-when-compile (unless (fboundp 'some-new-thing) (defmacro 'some-new-thing () (compatibility code))))Это часто полезно для кода, который является только резервным вариантом для обеспечения совместимости с другими версиями Emacs.
Примечание Common Lisp: На верхнем уровне
eval-when-compileаналогичен выражению Common Lisp(eval-when (compile eval) …). В других случаях макрос чтения Common Lisp '#.' (но не при интерпретации) ближе к тому, что делаетeval-when-compile.
Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Eval-During-Compile.html