我们说我有一个模块" foo.rkt"它导出一个struct foo,例如,
#lang racket (provide foo) (struct foo ())
在另一个模块中,我使用" foo.rkt"但我也想将绑定与" struct foo"到另一个命名空间(由于各种原因,我不使用预制件,所以我不能使用命名空间 - )。
我认为我可以使用namespace-attach-module,如下所示:
(define ns (make-base-namespace))
(namespace-attach-module (current-namespace) "foo.rkt" ns)
(eval '(foo) ns)
但这不起作用,因为名称空间映射符号显示s未绑定在ns中(如果这是查找绑定的唯一位置)。然而它确实在REPL中起作用。为什么呢?
答案 0 :(得分:5)
我认为问题是要避免在" foo.rkt"中实例化模块。两次,因为这会导致两个不兼容的结构定义。
函数namespace-attach-module
是谜题的一部分,但它只是附加
命名空间ns的实例化模块 - 即名称" foo.rkt"现在与" foo.rkt"的正确实例化相关联。然而,它并没有在ns中提供绑定 - 这是namespace-require
的工作。
以下是一个例子:
文件:" computer.rkt"
#lang racket
(provide (struct-out computer))
(struct computer (name price) #:transparent)
文件:" use-computer.rkt"
#lang racket
(require "computer.rkt") ; instatiate "computer.rkt"
(define ns (make-base-namespace))
(namespace-attach-module (current-namespace) "computer.rkt" ns) ; ns now knows the same instance
(define a-computer
(parameterize ([current-namespace ns])
(namespace-require "computer.rkt")
(eval '(computer "Apple" 2000) ns)))
(computer-name a-computer) ; works, since ns used the same instantiation of "computer.rkt"
运行它的结果是:
"Apple"
请注意,删除namespace-attach-module
行会导致错误:
computer-name: contract violation;
given value instantiates a different structure type with the same name
expected: computer?
given: (computer "Apple" 2000)
由于没有附件,namespace-require
将启动" computer.rkt"第二次开始宣布两个不兼容的结构。