Racket模块导入基础知识

4

我正在使用Racket,尝试在一个文件中require另一个文件。这两个文件都在同一个文件夹中,分别为world.rktant.rkt

world.rkt文件内容如下:

(module world racket
  (provide gen-grid gen-cell)

  (define (gen-cell item fill)
    (cons item fill))

  (define (gen-grid x y fill)
    (begin
      (define (gen-row x fill)
        (cond ((> x 0) (cons (gen-cell (quote none) fill)
                             (gen-row (- x 1) fill)))
              ((<= x 0) (quote ()) )))

      (cond ((> y 0) (cons (gen-row x fill)
                           (gen-grid x (- y 1) fill)))
            ((<= y 0) (quote ()) )))))

ant.rkt:

(module ant racket
  (require "world.rkt")

  (define (insert-ant grid x y)
    (cond ((> y 0) (insert-ant (cdr grid) x (- y 1)))
          ((< y 0) 'Error)
          ((= y 0) (begin
                     (define y-line (car grid))
                     (define (get-x line x)
                       (cond ((> x 0) (get-x (cdr line) (- x 1)))
                             ((< x 0) 'Error)
                             (= x 0) (gen-cell 'ant (cdr (car line))) ))

                     (get-x y-line x))))))

现在,我可以在REPL中键入(require "ant.rkt"),然后当我键入(gen-cell 'none 'white)时,会出现错误:
reference to undefined identifier: gen-cell  

我查阅了有关导入和导出的文档,但我无法正确地导入它。我觉得这是一些很简单的语法问题,我还没有弄明白。

我应该如何更改我的代码,以便我可以在ant.rkt中使用gen-gridgen-cell


1
也许你应该阅读这篇文章:https://dev59.com/V2445IYBdhLWcg3wia6W - Eineki
不,那个问题是关于无模块代码的“include”。但在这个问题中,dbmikus已经在使用模块,所以他的起点更好。 - Eli Barzilay
1个回答

6

您的代码看起来很好,我测试时没有出现问题。

但请注意两点:

  1. 现在最好使用#lang racket(或#lang racket/base)开始编写代码。不仅这已成为约定俗成的做法,而且它允许使用语言提供的任何语法扩展,而module则意味着您正在使用默认的sexpr。(顺便说一句,这样做也更方便,因为您不需要将模块名称与文件名相同。)

  2. 使用load加载模块可能并不是您想要的结果。最好是在了解其作用之前避免使用load,至少要知道它和eval一样糟糕。相反,您应该始终坚持使用require。当您掌握一些更多的知识时,可以看到有时dynamic-require也很有用,但现在先避开load


Eli,你没有提到在“load”之外使用什么;我假设你建议使用“require”或者只需在命令行上调用文件。 - John Clements
好的,我稍微修改了一下我的代码。现在已经反映在问题中了。我可以输入(require "ant.rkt"),但是当我调用(gen-cell 'none 'white)时,会出现一个错误消息,说gen-cell未定义。它似乎应该导入"world.rkt"。我该怎么解决这个问题? - dbmikus
1
啊,这就更容易回答了:你应该从 repl 中 require world.rkt,或者重新从 ant.rktprovide gen-cell 绑定。例如,可以参考 all-from-out - Eli Barzilay
那么你的意思是我只需要一个 #lang racket(module ... 是吗?我理解得对吗?这是否意味着当我写 #lang racket 时它会自动创建一个模块? - Zelphir Kaltstahl
@LeifAndersen,我认为是这样的,假设您会继续鼓励使用#lang而不是(module ...) - Eli Barzilay
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接