2016-05-20 44 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的代码。

相关问题