问题描述
我有一组非常简单的 .rkt
源代码,比如a.rkt"和b.rkt".我希望能够在b.rkt"中编写 (require "a.rkt")
,反之亦然.现在我面临关于加载周期"的错误.
I have quite simple set of .rkt
sources and, say, "a.rkt" and "b.rkt" among them. I'd like to be able to write (require "a.rkt")
in "b.rkt" and vice versa. Now I'm facing error about "loading cycle".
我可以在不添加单元的情况下使用裸模块解决这个问题吗?Racket 是否有类似于前向声明的东西,所以我可以简单地添加缺少的签名而不是要求?如果两个答案都是否",是否有人知道如何使用 typed/racket
(官方文档的旁边)实现单元的良好且易于理解的教程?
Can I solve this issue with bare modules without adding units? Does Racket have anything similar to forward declaration so I could simple add missing signature instead of requiring? If both answers are "No", does someone know good and understandable tutorial on how to implement units with typed/racket
(aside of official docs)?
推荐答案
您可以使用 懒惰要求
:
You can use 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!
实现的.
Notice that you must tell lazy-require
the specific things you want to import. That's because it is implemented in terms of dynamic-require
plus set!
.
如果您查看 源对于 xrepl
,你会看到它定义了一个 defautoload
宏,它(以一些 N/A 细节为模)很简单:
If you peek at the source for xrepl
, you'll see it define a defautoload
macro, which (modulo some N/A details) is simply:
(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))))
...))
这篇关于如何避免球拍中的加载循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!