D 语言 - 模块
模块是 D 的构建块。它们基于一个简单的概念。 每个源文件都是一个模块。 因此,我们编写程序的单个文件是单独的模块。 默认情况下,模块的名称与其文件名相同,不带 .d 扩展名。
显式指定时,模块的名称由 module 关键字定义,该关键字必须显示为源文件中的第一个非注释行。 例如,假设源文件的名称是"employee.d"。 然后模块的名称由 module 关键字指定,后跟 employee。 如下图所示。
module employee; class Employee { // Class definition goes here. }
模块行是可选的。 未指定时,与不带 .d 扩展名的文件名相同。
文件和模块名称
D 支持源代码和模块名称中的 Unicode。 但是,文件系统的 Unicode 支持各不相同。 例如,虽然大多数Linux文件系统都支持Unicode,但Windows文件系统中的文件名可能不区分大小写字母。 此外,大多数文件系统都限制文件名和目录名中可以使用的字符。 出于可移植性的原因,建议您在文件名中仅使用小写 ASCII 字母。 例如,"employee.d"对于名为employee 的类来说是一个合适的文件名。
因此,模块的名称也将由 ASCII 字母组成 −
module employee; // 由 ASCII 字母组成的模块名称 class eëmployëë { }
D 包
相关模块的组合称为包。 D 包也是一个简单的概念:同一目录内的源文件被认为属于同一个包。 目录的名称成为包的名称,也必须将其指定为模块名称的第一部分。
例如,如果"employee.d"和"office.d"位于目录"company"内,则指定目录名称和模块名称将使它们成为同一包的一部分 −
module company.employee; class Employee { }
类似地,对于office模块 −
module company.office; class Office { }
由于包名称与目录名称相对应,因此比一层目录级别更深的模块的包名称必须反映该层次结构。 例如,如果"company"目录包含"branch"目录,则该目录内的模块名称也将包含branch。
module company.branch.employee;
在程序中使用模块
到目前为止,我们几乎在每个程序中都使用了 import 关键字,它用于将模块引入到当前模块中 −
import std.stdio;
模块名称也可能包含包名称。例如,std。上面的部分表明 stdio 是一个模块,是 std 包的一部分。
模块位置
编译器通过将包名和模块名直接转换为目录名和文件名来查找模块文件。
例如,employee 和 office 这两个模块将分别位于"company/employee.d"和"animal/office.d"(或"company\employee.d"和"company\office.d") ,具体取决于文件系统)用于company.employee和company.office。
长模块名称和短模块名称
程序中使用的名称可以与模块和包名称一起拼写,如下所示。
import company.employee; auto employee0 = Employee(); auto employee1 = company.employee.Employee();
通常不需要长名称,但有时会出现名称冲突。 例如,当引用出现在多个模块中的名称时,编译器无法决定指的是哪一个。 以下程序拼写出长名称,以区分在两个单独模块中定义的两个单独的 employee 结构:company 和 college.。
文件夹company中的第一个employee模块如下。
module company.employee; import std.stdio; class Employee { public: string str; void print() { writeln("Company Employee: ",str); } }
文件夹college中的第二个employee模块如下。
module college.employee; import std.stdio; class Employee { public: string str; void print() { writeln("College Employee: ",str); } }
hello.d 中的主模块应保存在包含 College 和 Company 文件夹的文件夹中。 如下。
import company.employee; import college.employee; import std.stdio; void main() { auto myemployee1 = new company.employee.Employee(); myemployee1.str = "emp1"; myemployee1.print(); auto myemployee2 = new college.employee.Employee(); myemployee2.str = "emp2"; myemployee2.print(); }
import 关键字不足以使模块成为程序的一部分。 它只是使当前模块内的模块功能可用。 仅编译代码就需要这么多。
要构建上述程序,还必须在编译行中指定"company/employee.d"和"college/employee.d"。
当上面的代码被编译并执行时,会产生以下结果 −
$ dmd hello.d company/employee.d college/employee.d -ofhello.amx $ ./hello.amx Company Employee: emp1 College Employee: emp2