在D中导入模块

Red*_*age 7 module d

我试图在D(语言版本2)中使用基本模块导入.作为指南,我在dlang.org上使用了示例,但我的简单程序无法编译.这些文件位于同一目录中.

这是我的main.d文件的内容:

import std.stdio;
import mymodule;

void main(string[] args){
  sayHello();
  writeln("Executing Main");
}
Run Code Online (Sandbox Code Playgroud)

这是我的模块文件的内容(mymodule.d):

void sayHello(){
  writeln("hello");

}
Run Code Online (Sandbox Code Playgroud)

要编译我通过bash执行:

dmd main.d
Run Code Online (Sandbox Code Playgroud)

错误输出是:

main.o: In function `_Dmain':
main.d:(.text._Dmain+0x5): undefined reference to `_D8mymodule8sayHelloFZv'
collect2: ld returned 1 exit status
--- errorlevel 1
Run Code Online (Sandbox Code Playgroud)

Jon*_*vis 10

  1. 您需要列出您在命令行上编译的所有模块.如果您没有列出模块,那么它将不会被编译.该模块编译就可以使用未编译的模块,因为编译器在其声明中拉,但是编译器生成对象文件他们.因此,当链接器进行链接时,它会抱怨缺少定义.在这种情况下,它抱怨mymodule.sayHello尚未定义的事实.

    如果您希望编译器自动搜索第一个模块导入的所有模块并为您编译所有模块,那么您将需要使用rdmd,它是dmd的包装器,它随dmd一起提供.dmd本身并不这样做.它只编译你告诉它的模块.

  2. 你没有std.stdio在mymodule中导入.所以,即使你dmd main.d mymodule.d喜欢你应该(甚至更好,dmd -w main.d mymodule.ddmd -wi main.d mymodule.d),它也将无法编译mymodule,因为writeln尚未声明.main.d导入它对mymodule没有影响.

  3. 虽然在这种情况下这不是什么大问题,但您真的应该module modulename;在模块的顶部放置一个声明.编译器将从文件名推断模块名称,但是一旦你有子包,你要这样做,或者你会有导入问题,因为只推断了文件名,而不是包名.所以,如果你有foo/bar/mod.d,并且你没有module声明mod.d,那么它将被推断为mod,而不是foo.bar.mod.


Tyl*_*ves 5

dmd mymodule.d main.d

我所知道的唯一足够聪明的语言是 Go 和 Haskell。

  • `rdmd` 将计算出依赖关系。`rdmd main.d` 将构建文件和所有依赖项并执行结果。如果您只想构建,请在命令中添加 `--build-only`。 (3认同)
  • 迂腐说,我认为 Go 或 Haskell 都没有这个功能,而是他们的编译器有。符合标准的 D 编译器也可以拥有它。 (2认同)