- D 编程基础
- D 编程 - 首页
- D 编程 - 概述
- D 编程 - 环境
- D 编程 - 基本语法
- D 编程 - 变量
- D 编程 - 数据类型
- D 编程 - 枚举
- D 编程 - 字面量
- D 编程 - 运算符
- D 编程 - 循环
- D 编程 - 条件判断
- D 编程 - 函数
- D 编程 - 字符
- D 编程 - 字符串
- D 编程 - 数组
- D 编程 - 关联数组
- D 编程 - 指针
- D 编程 - 元组
- D 编程 - 结构体
- D 编程 - 联合体
- D 编程 - 范围
- D 编程 - 别名
- D 编程 - 混合宏
- D 编程 - 模块
- D 编程 - 模板
- D 编程 - 不可变对象
- D 编程 - 文件 I/O
- D 编程 - 并发
- D 编程 - 异常处理
- D 编程 - 合约
- D - 条件编译
- D 编程 - 面向对象
- D 编程 - 类与对象
- D 编程 - 继承
- D 编程 - 重载
- D 编程 - 封装
- D 编程 - 接口
- D 编程 - 抽象类
- D 编程 - 有用资源
- D 编程 - 快速指南
- D 编程 - 有用资源
- D 编程 - 讨论
D 编程 - 模块
模块是 D 的构建块。它们基于一个简单的概念。每个源文件都是一个模块。因此,我们编写程序的单个文件是独立的模块。默认情况下,模块的名称与其文件名相同,但不包括 .d 扩展名。
当显式指定时,模块的名称由 module 关键字定义,该关键字必须作为源文件中的第一行非注释行出现。例如,假设源文件名为“employee.d”。那么模块的名称由module关键字后跟employee指定。如下所示。
module employee; class Employee { // Class definition goes here. }
module 行是可选的。当未指定时,它与文件名相同,但不包括 .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 { }
同样,对于 office 模块 -
module company.office; class Office { }
由于包名称对应于目录名称,因此深度超过一级目录的模块的包名称必须反映这种层次结构。例如,如果“company”目录包含一个“branch”目录,则该目录中模块的名称也将包含 branch。
module company.branch.employee;
在程序中使用模块
我们到目前为止几乎在每个程序中都使用过的 import 关键字用于将模块引入当前模块 -
import std.stdio;
模块名称也可以包含包名称。例如,上面的 std. 部分表示 stdio 是 std 包的一部分的模块。
模块的位置
编译器通过将包和模块名称直接转换为目录和文件名来查找模块文件。
例如,对于 company.employee 和 company.office,两个模块 employee 和 office 将分别位于“company/employee.d”和“animal/office.d”(或“company\employee.d”和“company\office.d”,具体取决于文件系统)。
长模块名和短模块名
程序中使用的名称可以像下面这样用模块和包名称拼写出来。
import company.employee; auto employee0 = Employee(); auto employee1 = company.employee.Employee();
通常不需要长名称,但有时会出现名称冲突。例如,当引用出现在多个模块中的名称时,编译器无法确定哪个名称是目标。以下程序正在拼写长名称以区分在两个单独的模块:company 和 college 中定义的两个单独的employee 结构体。
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