2016-05-20 82 views

回答

3

聲明一個模塊就是這個模塊在當前命名空間的某個地方。這可以通過一個需求來完成,或者直接在代碼中寫出模塊。

模塊訪問並實例化是比較麻煩一些理解,並且可以被描述爲這樣:

  1. 模塊來訪運行階段電平1(宏/編譯時間碼),並沒有運行相級別0(運行時間代碼)。

  2. 模塊實例化運行相位0級代碼,但不運行相位1級代碼。現在

,棘手位,運行相平0的代碼,你必須有以前運行所有的更高水平的分階段的代碼,如果它沒有被編譯。但是,如果此模塊已被訪問(並編譯),它將不會再次運行階段1的代碼。

這可以被看作具有以下模塊,稱爲test.rkt

#lang racket 

(require (for-meta 2 racket/base)) 
(displayln "phase 0") 
(begin-for-syntax 
    (displayln "phase 1") 
    (begin-for-syntax 
    (displayln "phase 2"))) 

該模塊具有運行在相位0,相位1碼和相位2(用於宏膨脹階段宏擴展)。在每個階段中,它會打印出一行來指示階段正在運行。使用這個模塊,我們可以看到模塊何時被實例化。

現在,讓我們創建以下文件,該文件實例test.rkt

#lang racket 
(dynamic-require "test.rkt" #f) 

如果我們DrRacket運行此,輸出將類似於:

phase 2 
phase 1 
phase 0 

現在,我們看到phase 0因爲模塊正在被實例化。但是,在這種情況下,我們還會看到phase 2phase 1,因爲模塊的語法階段必須實例化以運行phase 0代碼。

但是,如果你再運行它(假設你已經編譯的文件緩存打開),您將獲得:

phase 0 

在這種情況下,你只能看到phase 0因爲phase 1和更高的代碼已經已擴大。我們也可以給0動態要求類似的結果。現在

,如果不是在0#f傳遞給dynamic-require,我們在(void)過去了,給我們以下文件:再次

#lang racket 
(dynamic-require "test.rkt" (void)) 

然後輸出將是(假設你有編譯緩存打開),看起來像:

phase 1 

這是因爲宏觀層面(階段1)代碼這裏正在運行,而不是運行時(相位0)代碼。但如果我們對test.rkt的微小變化,並再次將其保存(無效緩存),我們將得到:

phase 2 
phase 1 

這是因爲球拍不得不擴大phase 2代碼,以便能夠運行phase 1碼。現在,編譯的模塊緩存已經更新,如果您再次運行它,它只會輸出:

phase 1 

最後,沒有(據我所看到的,請更新這一點,如果我錯了) ,任何直接使用dynamic-require的方式都可以保證運行高於階段1的代碼。

相關問題