關於 EVAL-WHEN 的一點理解

EVAL-WHEN:  special operator

功能:控制求值時間點。

使用方式 :

(EVAL-WHEN (opt-list) body)

opt-list: 包括 :compile-toplevel ,:load-toplevel, :execute三個選項

body: 任意合法lisp表達式

------------------------------------------------------------------------------------------------------------------------------

1)、compile-toplevel : 在代碼編譯時求值body,加載及運行時看不到body求值結果。

         a. 輔助宏的函數,需要此選項

         b. 希望在compile時生成一些固定的信息,比如版本,編譯時間等信息時可使用此選項

2)、load-toplevel    :  在加載代碼時求值body求值結果

        a. 實現此效果的還有另外三種方式:一種爲通過special operator load-time-value;另一種爲通過special operator  macrolet都可以達到加載時求值的效果,最後一種爲閉包,閉包更爲通用。例如在記錄程序開始運行時間的三種實現

;;; 始終表現爲加載時的時間點
(defun get-begin-time-1 nil
     (load-time-value (get-universal-time)))

;;; 直接加載源碼時表現爲加載時的時間點;compile之後,表現爲編譯時的時間點
(defun get-begin-time-2 nil
     (macrolet ((begin-time nil (get-universal-time)))
      (begin-time)))

;;; 運行時求值,閉包實現: 始終表現爲加載時的時間點
(let ((begin-time (get-universal-time)))
    (defun get-begin-time-3 nil
         begin-time))  

;;; 加載時求值
(eval-when (:load-toplevel)  
    (let ((begin-time (get-universal-time)))
        (defun get-begin-time-4 nil
             begin-time)))
;;;測試
(mapcar #'funcall '(get-begin-time-1 get-begin-time-2 get-begin-time-3 get-begin-time-4))

        b. 頂層表達式及progn的子表達式都會在load時求值。

3)、execute            : 在代碼執行時求值。此爲大部分情形下的默認方式。

      可以與其它兩個選項組合使用,當execute選項時,表示運行時還會求值;而其它兩個選項只在待定的情形下適用。

 

發佈了77 篇原創文章 · 獲贊 11 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章