Модули являются строительными блоками языка D. Они основаны на простой концепции. Каждый исходный файл является модулем. Соответственно, единственными файлами, в которых мы пишем программы, являются отдельные модули. По умолчанию имя модуля совпадает с именем файла без расширения .d.
При явном указании имя модуля определяется ключевым словом module, которое должно находиться на первой строке, не являющейся комментарием в исходном файле. Например, предположим, что имя исходного файла – «employee.d». Тогда имя модуля указывается ключевым словом module, за которым следует employee. Это показано ниже.
Слово «employee» означает «сотрудник», оно используется во всех примерах этого раздела – прим. пер.
module employee; class Employee { // Определение класса находится здесь. }
Строка объявления модуля не обязательна. Если она не указана, имя модуля такое же, как и имя файла без расширения .d.
D поддерживает Unicode в исходном тексте и именах модулей. Однако поддержка Unicode файловыми системами различна. Например, хотя большинство файловых систем в Linux поддерживают Unicode, файловые системы Windows могут не различать буквы нижнего и верхнего регистра для имён файлов. Кроме того, большинство файловых систем ограничивают набор символов, которые могут использоваться для имён файлов и каталогов. Из соображений переносимости я рекомендую использовать для файлов только буквы ASCII в нижнем регистре. Например, «employee.d» будет подходящим именем файла для класса с именем employee.
Соответственно, имя модуля также будет состоять из букв ASCII:
module employee; // Имя модуля, состоящее из букв ASCII class eëmployëë { }
Комбинация связанных между собой модулей называется пакетом. В 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 будут расположены соответственно в файлах «company/employee.d» и «company/office.d» (или в «company\employee.d» и «company\office.d», в зависимости от файловой системы).
Имена, которые используются в программе, можно указывать с именами модулей и пакетов, как показано ниже.
import company.employee; auto employee0 = Employee(); auto employee1 = company.employee.Employee();
Длинные имена обычно не нужны, но иногда возникают конфликты имен. Например, при обращении к имени, которое появляется в нескольких модулях, компилятор не может решить, какой из них имеется в виду. В следующей программе используются длинные имена, чтобы различать два отдельных класса employee, объявленные в двух различных модулях: company и college.
Первый модуль employee в каталоге company выглядит следующим образом.
module company.employee; import std.stdio; class Employee { public: string str; void print() { writeln("Сотрудник компании: ", str); } }
Второй модуль employee в каталоге college выглядит следующим образом.
module college.employee; import std.stdio; class Employee { public: string str; void print() { writeln("Сотрудник колледжа: ", str); } }
Основной модуль в файле hello.d должен быть сохранён в каталоге, содержащем каталоги college и company. Он выглядит следующим образом.
import company.employee; import college.employee; import std.stdio; void main() { auto myemployee1 = new company.employee.Employee(); myemployee1.str = "сотрудник1"; myemployee1.print(); auto myemployee2 = new college.employee.Employee(); myemployee2.str = "сотрудник2"; myemployee2.print(); }
Ключевого слова import недостаточно для того, чтобы модули стали частью программы. Оно просто предоставляет сущности, объявленные в импортируемом модуле, внутри текущего модуля. Это необходимо только для компиляции кода.
Для вышеприведенной программы необходимо также указать «company/employee.d» и «college/employee.d» в командной строке компиляции.
When the above code is compiled and executed, it produces the following result −
$ dmd hello.d company/employee.d college/employee.d -ofhello $ ./hello Сотрудник компании: сотрудник1 Сотрудник колледжа: сотрудник2