|
@@ -1,34 +1,34 @@
|
|
|
# 11. Расширение масштаба
|
|
|
|
|
|
-[11.1. Пакеты и модули](#11-1-пакеты-и-модули)
|
|
|
- [11.1.1. Объявления import]()
|
|
|
- [11.1.2. Базовые пути поиска модулей]()
|
|
|
- [11.1.3. Поиск имен]()
|
|
|
- [11.1.4. Объявления public import]()
|
|
|
- [11.1.5. Объявления static import]()
|
|
|
- [11.1.6. Избирательные включения]()
|
|
|
- [11.1.7. Включения с переименованием]()
|
|
|
- [11.1.8. Объявление модуля]()
|
|
|
- [11.1.9. Резюме модулей]()
|
|
|
-[11.2. Безопасность]()
|
|
|
- [11.2.1. Определенное и неопределенное поведение]()
|
|
|
- [11.3.2. Атрибуты @safe, @trusted и @system]()
|
|
|
-[11.3. Конструкторы и деструкторы модулей]()
|
|
|
- [11.3.1. Порядок выполнения в рамках модуля]()
|
|
|
- [11.3.2. Порядок выполнения при участии нескольких модулей]()
|
|
|
-[11.4. Документирующие комментарии]()
|
|
|
-[11.5. Взаимодействие с C и C++]()
|
|
|
- [11.5.1. Взаимодействие с классами C++]()
|
|
|
-[11.6. Ключевое слово deprecated]()
|
|
|
-[11.7. Объявления версий]()
|
|
|
-[11.8. Отладочные объявления]()
|
|
|
-[11.9. Стандартная библиотека D]()
|
|
|
-[11.10. Встроенный ассемблер]()
|
|
|
- [11.10.1. Архитектура x86]()
|
|
|
- [11.10.2. Архитектура x86-64]()
|
|
|
- [11.10.3. Разделение на версии]()
|
|
|
- [11.10.4. Соглашения о вызовах]()
|
|
|
- [11.10.5. Рациональность]()
|
|
|
+- [11.1. Пакеты и модули](#11-1-пакеты-и-модули)
|
|
|
+ - [11.1.1. Объявления import](#11-1-1-объявления-import)
|
|
|
+ - [11.1.2. Базовые пути поиска модулей]()
|
|
|
+ - [11.1.3. Поиск имен]()
|
|
|
+ - [11.1.4. Объявления public import]()
|
|
|
+ - [11.1.5. Объявления static import]()
|
|
|
+ - [11.1.6. Избирательные включения]()
|
|
|
+ - [11.1.7. Включения с переименованием]()
|
|
|
+ - [11.1.8. Объявление модуля]()
|
|
|
+ - [11.1.9. Резюме модулей]()
|
|
|
+- [11.2. Безопасность]()
|
|
|
+ - [11.2.1. Определенное и неопределенное поведение]()
|
|
|
+ - [11.3.2. Атрибуты @safe, @trusted и @system]()
|
|
|
+- [11.3. Конструкторы и деструкторы модулей]()
|
|
|
+ - [11.3.1. Порядок выполнения в рамках модуля]()
|
|
|
+ - [11.3.2. Порядок выполнения при участии нескольких модулей]()
|
|
|
+- [11.4. Документирующие комментарии]()
|
|
|
+- [11.5. Взаимодействие с C и C++]()
|
|
|
+ - [11.5.1. Взаимодействие с классами C++]()
|
|
|
+- [11.6. Ключевое слово deprecated]()
|
|
|
+- [11.7. Объявления версий]()
|
|
|
+- [11.8. Отладочные объявления]()
|
|
|
+- [11.9. Стандартная библиотека D]()
|
|
|
+- [11.10. Встроенный ассемблер]()
|
|
|
+ - [11.10.1. Архитектура x86]()
|
|
|
+ - [11.10.2. Архитектура x86-64]()
|
|
|
+ - [11.10.3. Разделение на версии]()
|
|
|
+ - [11.10.4. Соглашения о вызовах]()
|
|
|
+ - [11.10.5. Рациональность]()
|
|
|
|
|
|
Поговорка гласит, что программу в 100 строк можно заставить работать, даже если она нарушает все законы правильного кодирования. Эта поговорка расширяема: действительно, можно написать программу в 10 000 строк, уделяя внимание лишь деталям кода и не соблюдая никаких более масштабных правил надлежащей модульной разработки. Возможно, где-то есть и проекты в несколько миллионов строк, нарушающие немало правил крупномасштабной разработки.
|
|
|
|
|
@@ -66,6 +66,60 @@
|
|
|
|
|
|
[В начало ⮍](#11-1-пакеты-и-модули) [Наверх ⮍](#11-расширение-масштаба)
|
|
|
|
|
|
+### 11.1.1. Объявления import
|
|
|
+
|
|
|
+Для получения доступа к благам стандартной библиотеки в примерах кода из предыдущих глав обычно использовалась инструкция `import`:
|
|
|
+
|
|
|
+```d
|
|
|
+import std.stdio; // Получить доступ к writeln и всему остальному
|
|
|
+```
|
|
|
+
|
|
|
+Чтобы включить один модуль в другой, укажите имя модуля в объявлении `import`. Имя модуля должно содержать путь до него относительно каталога, где выполняется компиляция. Рассмотрим пример иерархии каталогов (рис. 11.1).
|
|
|
+
|
|
|
+Предположим, компиляция выполняется в каталоге `root`. Чтобы получить доступ к определениям файла `widget.d` из любого другого файла, этот другой файл должен содержать объявление верхнего уровня:
|
|
|
+
|
|
|
+```d
|
|
|
+import widget;
|
|
|
+```
|
|
|
+
|
|
|
+![]()
|
|
|
+
|
|
|
+***Рис. 11.1.*** *Пример структуры каталога*
|
|
|
+
|
|
|
+«Объявление верхнего уровня» – это объявление вне всех контекстов (таких как функция, класс и структура)[^4]. Встретив это объявление `import`, компилятор начнет искать `widget.di` (сначала) или `widget.d` (потом) начиная с каталога `root`, найдет `widget.d` и импортирует его идентификаторы. Чтобы использовать файл, расположенный глубже в иерархии каталогов, другой файл проекта должен содержать объявление `import` с указанием относительного пути до него от каталога `root` с точкой `.` в качестве разделителя:
|
|
|
+
|
|
|
+```d
|
|
|
+import acme.gadget;
|
|
|
+import acme.goodies.io;
|
|
|
+```
|
|
|
+
|
|
|
+В объявлениях import мы обычно используем списки значений, разделенных запятыми. Два предыдущих объявления эквивалентны следующему:
|
|
|
+
|
|
|
+```d
|
|
|
+import acme.gadget, acme.goodies.io;
|
|
|
+```
|
|
|
+
|
|
|
+Обратите внимание: файл, расположенный на более низком уровне иерархии каталогов, такой как `gadget.d`, *также* должен указывать путь к другим файлам относительно каталога `root`, где выполняется компиляция, а не относительно собственного расположения. Например, чтобы получить доступ к идентификаторам файла `io.d`, файл `gadget.d` должен содержать объявление:
|
|
|
+
|
|
|
+```d
|
|
|
+import acme.goodies.io;
|
|
|
+```
|
|
|
+
|
|
|
+а не
|
|
|
+
|
|
|
+```d
|
|
|
+import goodies.io;
|
|
|
+```
|
|
|
+
|
|
|
+Другой пример: если файл `io.d` хочет включить файл `string.d`, то он должен содержать объявление `import acme.goodies.string`, хотя оба этих файла находятся в одном каталоге. Разумеется, в данном случае предполагается, что компиляция выполняется в каталоге `root`. Если вы перешли в каталог `acme` и компилируете `gadget.d` *там*, он должен содержать объявление `import goodies.io`.
|
|
|
+
|
|
|
+Порядок включения модулей не имеет значения. Язык задуман таким образом, что семантика модуля не зависит от порядка, в каком этот модуль включает другие модули.
|
|
|
+
|
|
|
+Объявление `import` присоединяет только идентификаторы (символы), следовательно, пакеты и модули на D должны иметь имена, являющиеся допустимыми идентификаторами языка D (см. раздел 2.1). Например, если у вас есть файл `5th_element.d`, то вы просто не сможете включить его в другой модуль, поскольку «5th_element» не является допустимым идентификатором D. Точно так же, если вы храните файлы в каталоге `input-output`, то не сможете использовать этот каталог как пакет D. Иными словами, все файлы и каталоги, содержащие исходный код на языке D, должны носить лишь имена, являющиеся допустимыми идентификаторами. Дополнительное соглашение: имена всех пакетов и модулей не содержат заглавных букв. Цель этого соглашения – предотвратить путаницу в операционных системах с нестрогой обработкой регистра букв в именах файлов.
|
|
|
+
|
|
|
+[В начало ⮍](#11-1-1-объявления-import) [Наверх ⮍](#11-расширение-масштаба)
|
|
|
+
|
|
|
[^1]: Прямой порядок байтов – от старшего к младшему байту. – *Прим. пер.*
|
|
|
[^2]: Обратный порядок байтов – от младшего к старшему байту. – *Прим. пер.*
|
|
|
[^3]: «Shebang» – от англ. *sharp-bang* или *hash-bang*, произношение символов `#!` – *Прим. науч. ред.*
|
|
|
+[^4]: Текущие версии реализации позволяют включать модули на уровне классов и функций. – *Прим. науч. ред.*
|