Common Lisp 中的#ifndef
#ifndef in Common Lisp
在 C 中,为确保我们不包含 re-include headers,我们使用以下结构:
#ifndef UTILS
#define UTILS
#include "my_utils.h"
#endif
我已经把我的 Lisp 程序分解成单独的文件;多个文件有时会使用同一个文件(例如,my_utilities 被多个文件使用)。当我 运行 程序时,我收到警告说我正在重新定义事物(多次调用同一文件的 load
)。
这可以通过在 C 中执行类似于 #ifndef
的操作来解决。执行此操作的 Common Lisp 等效方法或标准方法是什么?
我对 Lisp 还很陌生。让我知道是否有我缺少的最佳实践(也许是另一种构建程序的方法?)。
你问的问题
预处理器条件的直接模拟,如 C 中的 #if
是
#+
读取时条件化工具。
您想问的问题
为避免多次加载文件,您可以使用标准
(但已弃用)
provide
/require
设施,
或者像 ASDF.
这样的附加系统
对于 Common Lisp 应用程序和库,最好使用 系统 管理工具。像 ASDF 或您的实施可能提供的任何东西。系统是具有依赖关系和各种操作(加载、编译...)的文件的集合。
您可以随时检查 运行时间的状态并做一些事情。
示例:
(unless (fboundp 'foobar)
(require "foo")
(load "bar"))
(unless (find-package 'foobar)
(require "foo")
(load "bar"))
PROVIDE
和 REQUIRE
正是用于此目的的内置函数。如果你需要一个 模块 它将被加载,除非已经 provided
。不幸的是,此功能在标准中未指定,但实现可能会提供有用的功能。
Common Lisp 运行次在列表 *features*
中有一个 特性列表 。您可以使用它来宣传和检查功能。
示例:
在您的图书馆中:
(push :cool-new-graphics-library cl:*features*)
在您的应用代码中:
(when (member :cool-new-graphics-library cl:*features*)
(funcall (find-symbol "DRAW-SPACE-SHIP" "CNGL")
:death-star))
Common Lisp 提供了一种条件化 阅读时间 的方法。以下代码只有在 :cool-new-graphics-library
特性存在时才会被读取,因此它只会在以后执行:
#+cool-new-graphics-library(cngl:draw-space-ship :death-star)
Common Lisp 还允许您表达一些逻辑:
#+(and lispworks cool-new-graphics-library)
(cngl:draw-space-ship :enterprise)
#-cool-new-graphics-library(warn "no cool graphics library available")
请注意,您可以强制 Lisp 在编译时执行代码:
(eval-when (:load-toplevel :compile-toplevel :execute)
#+(and lispworks cool-new-graphics-library)
(cngl:draw-space-ship :enterprise)
#-cool-new-graphics-library(warn "no cool graphics library available")
)
为此,EVAL-WHEN
必须位于文件的顶层。这意味着它不会在嵌套表单中深入工作。不过,它确实在顶层 PROGN
、LOCALLY
、MACROLET
和 SYMBOL-MACROLET
中工作。
因此 EVAL-WHEN
允许您 运行 代码是当前编译文件的一部分。这段代码可以查找加载的系统、提供的模块、可用的函数等等。
在 C 中,为确保我们不包含 re-include headers,我们使用以下结构:
#ifndef UTILS
#define UTILS
#include "my_utils.h"
#endif
我已经把我的 Lisp 程序分解成单独的文件;多个文件有时会使用同一个文件(例如,my_utilities 被多个文件使用)。当我 运行 程序时,我收到警告说我正在重新定义事物(多次调用同一文件的 load
)。
这可以通过在 C 中执行类似于 #ifndef
的操作来解决。执行此操作的 Common Lisp 等效方法或标准方法是什么?
我对 Lisp 还很陌生。让我知道是否有我缺少的最佳实践(也许是另一种构建程序的方法?)。
你问的问题
预处理器条件的直接模拟,如 C 中的 #if
是
#+
读取时条件化工具。
您想问的问题
为避免多次加载文件,您可以使用标准
(但已弃用)
provide
/require
设施,
或者像 ASDF.
对于 Common Lisp 应用程序和库,最好使用 系统 管理工具。像 ASDF 或您的实施可能提供的任何东西。系统是具有依赖关系和各种操作(加载、编译...)的文件的集合。
您可以随时检查 运行时间的状态并做一些事情。
示例:
(unless (fboundp 'foobar)
(require "foo")
(load "bar"))
(unless (find-package 'foobar)
(require "foo")
(load "bar"))
PROVIDE
和REQUIRE
正是用于此目的的内置函数。如果你需要一个 模块 它将被加载,除非已经provided
。不幸的是,此功能在标准中未指定,但实现可能会提供有用的功能。Common Lisp 运行次在列表
*features*
中有一个 特性列表 。您可以使用它来宣传和检查功能。
示例:
在您的图书馆中:
(push :cool-new-graphics-library cl:*features*)
在您的应用代码中:
(when (member :cool-new-graphics-library cl:*features*)
(funcall (find-symbol "DRAW-SPACE-SHIP" "CNGL")
:death-star))
Common Lisp 提供了一种条件化 阅读时间 的方法。以下代码只有在 :cool-new-graphics-library
特性存在时才会被读取,因此它只会在以后执行:
#+cool-new-graphics-library(cngl:draw-space-ship :death-star)
Common Lisp 还允许您表达一些逻辑:
#+(and lispworks cool-new-graphics-library)
(cngl:draw-space-ship :enterprise)
#-cool-new-graphics-library(warn "no cool graphics library available")
请注意,您可以强制 Lisp 在编译时执行代码:
(eval-when (:load-toplevel :compile-toplevel :execute)
#+(and lispworks cool-new-graphics-library)
(cngl:draw-space-ship :enterprise)
#-cool-new-graphics-library(warn "no cool graphics library available")
)
为此,EVAL-WHEN
必须位于文件的顶层。这意味着它不会在嵌套表单中深入工作。不过,它确实在顶层 PROGN
、LOCALLY
、MACROLET
和 SYMBOL-MACROLET
中工作。
因此 EVAL-WHEN
允许您 运行 代码是当前编译文件的一部分。这段代码可以查找加载的系统、提供的模块、可用的函数等等。