如果我写一个像这样的 D 文件:http: //arsdnet.net/dcode/iface/test.d并且你用 dmd -c 编译,你会看到它没有错误;这是一个有效的 D 文件。该语言允许您编写没有实现的函数原型。
.di 文件就是这样,只是文件名不同。
然后给出main:http ://arsdnet.net/dcode/main.d如果你编译dmd main,它会在看到“import iface.test;”时自动搜索iface/test.d,找到那个.d文件,或者 .di 如果你重命名它但同样的东西,并得到你的接口定义。
dmd main 将因链接器错误而失败,因此我们需要实现它:http ://arsdnet.net/dcode/impl.d 注意:impl 不导入模块,因此它从不检查其他文件。保持 .di 和 .d 文件同步是这里的棘手部分之一,除非您自动生成接口文件,因为未定义的方法会产生链接器错误,但方法的顺序很重要:它必须匹配,所以这样做变量列表(如果有任何公共变量)。否则,使用代码和实现代码不会在类的布局上达成一致。
同样,它不会自动检查,实现文件根本不查看“头”文件,因此这与 C++ 的主要区别在于您编写头文件一次,然后在使用程序和实施文件。
您会注意到实现文件也列出了类等。D 不支持void MyClass::add(int a) {}
C++ 必须在类外编写方法的语法。
据我所知,没有办法强制实现文件查找头文件,如果将两者都放在命令行上,则会得到:“错误:来自文件 iface/test.d 的模块 iface.test 与另一个模块冲突从文件 impl.d 进行测试”
推荐使用 .di 文件的方式是使用 dmd -H 自动生成它们。这会读取完整的实现文件并去除函数体,只留下定义。当他们说它是编译器的一个功能时,这部分可能是关键 - .di 文件是有效的标准 D,但通过编译器选项生成,不一定需要是其他编译器的一部分。