2016-07-27 157 views
3

在C語言中,以確保我們不會再包括包含我們用以下結構標題:的#ifndef Common Lisp中

#ifndef UTILS 
#define UTILS 

#include "my_utils.h" 

#endif 

我已經打破了我的Lisp程序到單獨的文件;多個文件有時使用相同的文件(例如,my_utilities被多個文件使用)。當我運行該程序時,我收到警告說我正在重新定義事件(多次調用同一文件的load)。

這可以通過在C中執行與#ifndef類似的操作來解決。什麼是Common Lisp等效或標準方法?

我是Lisp的新手。讓我知道是否有最佳實踐(也許,我的程序的不同構造方法?),我錯過了。

+2

您應該使用[asdf](https://stackoverflow.com/documentation/common-lisp/670/asdf-another-system-definition-facility#t=20160727160132848467)來定義系統。 – jkiiski

+0

這就是我正在尋找的。謝謝。 – audrow

回答

7

你問

的預處理條件類似於C #if直接模擬的問題是, #+讀出時間條件化設施。

你想的問題要問

爲了避免文件的多個負載,您可以使用標準的 (但不建議使用) provide/require設施, 或附加系統,如ASDF

+0

這就是我想問的。謝謝。 – audrow

+1

不用客氣 – sds

6
  1. 對於Common Lisp的應用程序和庫,最好使用系統管理工具。像ASDF或任何你的實現可能提供。系統是具有依賴性和各種操作(加載,編譯,...)的文件的集合。

  2. 您可以隨時檢查運行時的狀態並執行一些操作。

實施例:

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

(unless (find-package 'foobar) 
    (require "foo") 
    (load "bar")) 
  • PROVIDEREQUIRE是內置函數對於這一點。如果您需要模塊它將被加載,除非已經有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必須是在一個文件中的頂層。這意味着它不會在嵌套表單中工作得很深。它一個頂級PROGNLOCALLYMACROLETSYMBOL-MACROLET裏面工作,雖然。

    因此EVAL-WHEN允許您運行代碼是當前編譯文件的一部分。這個代碼比可以查找加載的系統,提供的模塊,可用的函數等等。

    +0

    非常徹底。謝謝。 – audrow