模块(Modules)
模块是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; // Module name consisting of ASCII letters
class eëmployëë { }
D包
相关模块的组合称为包。 D包也是一个简单的概念:同一目录中的源文件被认为属于同一个包。 目录的名称将成为程序包的名称,该名称也必须指定为模块名称的第一部分。
例如,如果“employee.d”和“office.d”在目录“company”中,那么指定目录名称和模块名称使它们成为同一个包的一部分 -
module company.employee;
class Employee { }
同样,对于办公室模块 -
module company.office;
class Office { }
由于包名称对应于目录名称,因此深度超过一个目录级别的模块的包名称必须反映该层次结构。 例如,如果“company”目录包含“branch”目录,则该目录中的模块名称也将包含分支。
module company.branch.employee;
在程序中使用模块
到目前为止,我们几乎在每个程序中都使用了import关键字,用于将模块引入当前模块 -
import std.stdio;
模块名称也可以包含包名称。 例如,标准。 上面的部分表示stdio是std包的一部分的模块。
模块的位置
编译器通过将包和模块名称直接转换为目录和文件名来查找模块文件。
例如,员工和办公室这两个模块分别位于“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. 。
文件夹公司中的第一个员工模块如下。
module company.employee;
import std.stdio;
class Employee {
public:
string str;
void print() {
writeln("Company Employee: ",str);
}
}
文件夹学院的第二个员工模块如下。
module college.employee;
import std.stdio;
class Employee {
public:
string str;
void print() {
writeln("College Employee: ",str);
}
}
hello.d中的主模块应保存在包含学院和公司文件夹的文件夹中。 它如下。
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