This commit is contained in:
Alexander Zhirov 2023-02-28 21:16:32 +03:00
parent 11dd7816c0
commit f7d0cd578c
1 changed files with 83 additions and 29 deletions

View File

@ -1,34 +1,34 @@
# 11. Расширение масштаба # 11. Расширение масштаба
[11.1. Пакеты и модули](#11-1-пакеты-и-модули) - [11.1. Пакеты и модули](#11-1-пакеты-и-модули)
[11.1.1. Объявления import]() - [11.1.1. Объявления import](#11-1-1-объявления-import)
[11.1.2. Базовые пути поиска модулей]() - [11.1.2. Базовые пути поиска модулей]()
[11.1.3. Поиск имен]() - [11.1.3. Поиск имен]()
[11.1.4. Объявления public import]() - [11.1.4. Объявления public import]()
[11.1.5. Объявления static import]() - [11.1.5. Объявления static import]()
[11.1.6. Избирательные включения]() - [11.1.6. Избирательные включения]()
[11.1.7. Включения с переименованием]() - [11.1.7. Включения с переименованием]()
[11.1.8. Объявление модуля]() - [11.1.8. Объявление модуля]()
[11.1.9. Резюме модулей]() - [11.1.9. Резюме модулей]()
[11.2. Безопасность]() - [11.2. Безопасность]()
[11.2.1. Определенное и неопределенное поведение]() - [11.2.1. Определенное и неопределенное поведение]()
[11.3.2. Атрибуты @safe, @trusted и @system]() - [11.3.2. Атрибуты @safe, @trusted и @system]()
[11.3. Конструкторы и деструкторы модулей]() - [11.3. Конструкторы и деструкторы модулей]()
[11.3.1. Порядок выполнения в рамках модуля]() - [11.3.1. Порядок выполнения в рамках модуля]()
[11.3.2. Порядок выполнения при участии нескольких модулей]() - [11.3.2. Порядок выполнения при участии нескольких модулей]()
[11.4. Документирующие комментарии]() - [11.4. Документирующие комментарии]()
[11.5. Взаимодействие с C и C++]() - [11.5. Взаимодействие с C и C++]()
[11.5.1. Взаимодействие с классами C++]() - [11.5.1. Взаимодействие с классами C++]()
[11.6. Ключевое слово deprecated]() - [11.6. Ключевое слово deprecated]()
[11.7. Объявления версий]() - [11.7. Объявления версий]()
[11.8. Отладочные объявления]() - [11.8. Отладочные объявления]()
[11.9. Стандартная библиотека D]() - [11.9. Стандартная библиотека D]()
[11.10. Встроенный ассемблер]() - [11.10. Встроенный ассемблер]()
[11.10.1. Архитектура x86]() - [11.10.1. Архитектура x86]()
[11.10.2. Архитектура x86-64]() - [11.10.2. Архитектура x86-64]()
[11.10.3. Разделение на версии]() - [11.10.3. Разделение на версии]()
[11.10.4. Соглашения о вызовах]() - [11.10.4. Соглашения о вызовах]()
[11.10.5. Рациональность]() - [11.10.5. Рациональность]()
Поговорка гласит, что программу в 100 строк можно заставить работать, даже если она нарушает все законы правильного кодирования. Эта поговорка расширяема: действительно, можно написать программу в 10 000 строк, уделяя внимание лишь деталям кода и не соблюдая никаких более масштабных правил надлежащей модульной разработки. Возможно, где-то есть и проекты в несколько миллионов строк, нарушающие немало правил крупномасштабной разработки. Поговорка гласит, что программу в 100 строк можно заставить работать, даже если она нарушает все законы правильного кодирования. Эта поговорка расширяема: действительно, можно написать программу в 10 000 строк, уделяя внимание лишь деталям кода и не соблюдая никаких более масштабных правил надлежащей модульной разработки. Возможно, где-то есть и проекты в несколько миллионов строк, нарушающие немало правил крупномасштабной разработки.
@ -66,6 +66,60 @@
[В начало ⮍](#11-1-пакеты-и-модули) [Наверх ⮍](#11-расширение-масштаба) [В начало ⮍](#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]: Прямой порядок байтов от старшего к младшему байту. *Прим. пер.* [^1]: Прямой порядок байтов от старшего к младшему байту. *Прим. пер.*
[^2]: Обратный порядок байтов от младшего к старшему байту. *Прим. пер.* [^2]: Обратный порядок байтов от младшего к старшему байту. *Прим. пер.*
[^3]: «Shebang» от англ. *sharp-bang* или *hash-bang*, произношение символов `#!` *Прим. науч. ред.* [^3]: «Shebang» от англ. *sharp-bang* или *hash-bang*, произношение символов `#!` *Прим. науч. ред.*
[^4]: Текущие версии реализации позволяют включать модули на уровне классов и функций. *Прим. науч. ред.*