我有一组非常简单的.rkt
源,例如,其中有“ a.rkt”和“ b.rkt”。我希望能够在“ b.rkt”中写(require "a.rkt")
,反之亦然。现在,我遇到有关“加载周期”的错误。
我可以在不添加单元的情况下使用裸模块解决此问题吗? Racket是否具有类似于前向声明的内容,因此我可以简单地添加缺少的签名而不是要求?如果两个答案均为“否”,那么有人会知道如何使用typed/racket
(官方文档的 a )来实现单元的良好易懂的教程吗?
答案 0 :(得分:3)
您可以使用lazy-require
:
;; a.rkt
#lang racket
(require racket/lazy-require)
(lazy-require ["b.rkt" (b)])
(provide a)
(define (a) 'a)
(list (a) (b))
;; b.rkt
#lang racket
(require racket/lazy-require)
(lazy-require ["a.rkt" (a)])
(provide b)
(define (b) 'b)
(list (a) (b))
请注意,您必须告诉lazy-require
您要导入的特定内容。这是因为它是根据dynamic-require
加set!
来实现的。
如果窥视source for xrepl
,您会看到它定义了一个defautoload
宏,该宏(以一些N / A细节为模)很简单:
(define-syntax-rule (defautoload libspec id ...)
(begin
(define id
(make-keyword-procedure
(λ (kws kw-args . args)
(set! id (dynamic-require 'libspec 'id))
(keyword-apply id kws kw-args args))))
...))