Common Lisp中的#ifndef

aud*_*row 3 lisp clisp common-lisp include

在C中,为了确保我们不重新包含包含的标头,我们使用以下结构:

#ifndef UTILS
#define UTILS

#include "my_utils.h"

#endif
Run Code Online (Sandbox Code Playgroud)

我把我的Lisp程序分成了单独的文件; 多个文件有时使用相同的文件(例如,my_utilities由多个文件使用).当我运行程序时,我收到警告,我正在重新定义事物(load多次调用同一文件).

这可以通过执行类似于#ifndefC的操作来解决.Common Lisp等效或标准方法是什么?

我是Lisp的新手.让我知道我是否缺少最佳实践(也许是构建我的程序的不同方法?).

sds*_*sds 7

你问的问题

#ifC语言中预处理器条件的直接模拟是 #+读取时间条件化工具.

你想问的问题

为避免多次加载文件,您可以使用标准(但已弃用) provide/require工具或ASDF等附加系统.


Rai*_*wig 6

  1. 对于Common Lisp应用程序和库,最好使用系统管理工具.像ASDF或您的实施可能提供的任何内容.系统是具有依赖关系和各种操作(加载,编译,...)的文件的集合.

  2. 您始终可以检查运行时的状态并执行某些操作.

例:

(unless (fboundp 'foobar)
  (require "foo")
  (load "bar"))

(unless (find-package 'foobar)
  (require "foo")
  (load "bar"))
Run Code Online (Sandbox Code Playgroud)
  1. PROVIDE并且REQUIRE是内置函数.如果您需要一个模块,它将被加载,除非已经加载provided.遗憾的是,该功能在标准中未详细说明,但实现可能提供有用的功能.

  2. Common Lisp运行时具有列表中的功能列表*features*.您可以使用它来宣传和检查功能.

例:

在你的图书馆:

(push :cool-new-graphics-library cl:*features*)
Run Code Online (Sandbox Code Playgroud)

在您的应用代码中:

(when (member :cool-new-graphics-library cl:*features*)
  (funcall (find-symbol "DRAW-SPACE-SHIP" "CNGL")
           :death-star))
Run Code Online (Sandbox Code Playgroud)

Common Lisp提供了一种条件化读取时间的方法.只有当该:cool-new-graphics-library功能存在时才会读取以下代码,因此它只会在以后执行:

#+cool-new-graphics-library(cngl:draw-space-ship :death-star)
Run Code Online (Sandbox Code Playgroud)

Common Lisp还允许您表达一些逻辑:

#+(and lispworks cool-new-graphics-library)
  (cngl:draw-space-ship :enterprise)

#-cool-new-graphics-library(warn "no cool graphics library available")
Run Code Online (Sandbox Code Playgroud)

请注意,您可以强制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")
 )
Run Code Online (Sandbox Code Playgroud)

为了使其工作EVAL-WHEN,必须在文件的顶层.这意味着它无法在嵌套表单中深入工作.它一个顶层内工作PROGN,LOCALLY,MACROLETSYMBOL-MACROLET,虽然.

因此EVAL-WHEN,您可以运行代码,该代码是当前编译的文件的一部分.此代码可以查找已加载的系统,提供的模块,可用的功能等.