Язык программирования D

This document was uploaded by one of our users. The uploader already confirmed that they had the permission to publish it. If you are author/publisher or own the copyright of this documents, please report to us by using this DMCA report form.

Simply click on the Download Book button.

Yes, Book downloads on Ebookily are 100% Free.

Sometimes the book is free on Amazon As well, so go ahead and hit "Search on Amazon"

D - это язык программирования, цель которого - помочь программистам справиться с непростыми современными проблемами разработки программного обеспечения. Он создает все условия для организации взаимодействия модулей через точные интерфейсы, поддерживает целую федерацию тесно взаимосвязанных парадигм программирования (императивное, объектно-ориентированное, функциональное и метапрограммирование), обеспечивает изоляцию потоков, модульную безопасность типов, предоставляет рациональную модель памяти и многое другое. "Язык программирования D" - это введение в D, автору которого можно доверять. Это книга в фирменном стиле Александреску - она написана неформальным языком, но без лишних слов и не в ущерб точности. Андрей рассказывает о выражениях и инструкциях, о функциях, контрактах, модулях и о многом другом, что есть в языке D. В книге вы найдете полный перечень средств языка с объяснениями и наглядными примерами; описание поддержки разных парадигм программирования конкретными средствами языка D; информацию о том, почему в язык включено то или иное средство, и советы по их использованию; обсуждение злободневных вопросов, таких как обработка ошибок, контрактное программирование и параллельные вычисления. Книга написана для практикующего программиста, причем она не просто знакомит с языком - это настоящий справочник полезных методик и идиом, которые облегчат жизнь не только программиста на D, но и программиста вообще.

Author(s): Андрей Александреску
Publisher: Символ-Плюс
Year: 2012

Language: Russian
Commentary: True PDF
Pages: 533

Об авторе . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .13
Предисловие Уолтера Брайта . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14
Предисловие Скотта Мейерса . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .18
Предисловие научных редакторов перевода . . . . . . . . . . . . . . . . . . . .21
Введение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .23
Глава 1. Знакомство с языком D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .29
1.1. Числа и выражения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .31
1.2. Инструкции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34
1.3. Основы работы с функциями . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .35
1.4. Массивы и ассоциативные массивы . . . . . . . . . . . . . . . . . . . . . . . . . .36
1.4.1. Работаем со словарем . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .36
1.4.2. Получение среза массива. Функции с обобщенными
типами параметров. Тесты модулей . . . . . . . . . . . . . . . . . . . . . . . . . . .39
1.4.3. Подсчет частот. Лямбда-функции . . . . . . . . . . . . . . . . . . . . . . .41
1.5. Основные структуры данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .44
1.6. Интерфейсы и классы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .49
1.6.1. Больше статистики. Наследование . . . . . . . . . . . . . . . . . . . . . . .53
1.7. Значения против ссылок . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .55
1.8. Итоги . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .57
Глава 2. Основные типы данных. Выражения . . . . . . . . . . . . . . . . . . . . . . . . . .59
2.1. Идентификаторы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .61
2.1.1. Ключевые слова . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .61
2.2. Литералы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .62
2.2.1. Логические литералы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .62
2.2.2. Целые литералы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .63
2.2.3. Литералы с плавающей запятой . . . . . . . . . . . . . . . . . . . . . . . .64
2.2.4. Знаковые литералы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .66
2.2.5. Строковые литералы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .67
2.2.6. Литералы массивов и ассоциативных массивов . . . . . . . . . . . .72
2.2.7. Функциональные литералы . . . . . . . . . . . . . . . . . . . . . . . . . . . .73
2.3. Операции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .75
2.3.1. L-значения и r-значения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .75
2.3.2. Неявные преобразования чисел . . . . . . . . . . . . . . . . . . . . . . . . .76


6 Оглавление

2.3.3. Типы числовых операций . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .79
2.3.4. Первичные выражения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .80
2.3.5. Постфиксные операции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .84
2.3.6. Унарные операции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .86
2.3.7. Возведение в степень . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .89
2.3.8. Мультипликативные операции . . . . . . . . . . . . . . . . . . . . . . . . . .89
2.3.9. Аддитивные операции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .90
2.3.10. Сдвиг . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .90
2.3.11. Выражения in. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .91
2.3.12. Сравнение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .92
2.3.13. Поразрядные ИЛИ, ИСКЛЮЧАЮЩЕЕ ИЛИ и И . . . . . . . . .94
2.3.14. Логическое И . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .94
2.3.15. Логическое ИЛИ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .94
2.3.16. Тернарная условная операция . . . . . . . . . . . . . . . . . . . . . . . . . .95
2.3.17. Присваивание . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .95
2.3.18. Выражения с запятой . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .96
2.4. Итоги и справочник . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .96
Глава 3. Инструкции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .100
3.1. Инструкция-выражение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
3.2. Составная инструкция . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
3.3. Инструкция if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
3.4. Инструкция static if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
3.5. Инструкция switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .106
3.6. Инструкция final switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
3.7. Циклы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .109
3.7.1. Инструкция while (цикл с предусловием) . . . . . . . . . . . . . . . . 109
3.7.2. Инструкция do-while (цикл с постусловием) . . . . . . . . . . . . . . 109
3.7.3. Инструкция for (цикл со счетчиком) . . . . . . . . . . . . . . . . . . . . 109
3.7.4. Инструкция foreach (цикл просмотра) . . . . . . . . . . . . . . . . . . . 110
3.7.5. Цикл просмотра для работы с массивами . . . . . . . . . . . . . . . . 111
3.7.6. Инструкции continue и break . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
3.8. Инструкция goto (безусловный переход) . . . . . . . . . . . . . . . . . . . . . 114
3.9. Инструкция with . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
3.10. Инструкция return . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
3.11. Обработка исключительных ситуаций . . . . . . . . . . . . . . . . . . . . . . 117
3.12. Инструкция mixin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
3.13. Инструкция scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .120
3.14. Инструкция synchronized . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .125
3.15. Конструкция asm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .125
3.16. Итоги и справочник . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .126
Глава 4. Массивы, ассоциативные массивы и строки . . . . . . . . . . . . . . . . . .130
4.1. Динамические массивы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .130
4.1.1. Длина . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
4.1.2. Проверка границ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
4.1.3. Срезы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .134


Оглавление 7

4.1.4. Копирование. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
4.1.5. Проверка на равенство . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
4.1.6. Конкатенация . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
4.1.7. Поэлементные операции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
4.1.8. Сужение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .139
4.1.9. Расширение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
4.1.10. Присваивание значения свойству .length . . . . . . . . . . . . . . . 143
4.2. Массивы фиксированной длины . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
4.2.1. Длина . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
4.2.2. Проверка границ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
4.2.3. Получение срезов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
4.2.4. Копирование и неявные преобразования . . . . . . . . . . . . . . . . 147
4.2.5. Проверка на равенство . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
4.2.6. Конкатенация . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
4.2.7. Поэлементные операции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
4.3. Многомерные массивы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
4.4. Ассоциативные массивы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
4.4.1. Длина . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
4.4.2. Чтение и запись ячеек . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
4.4.3. Копирование . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
4.4.4. Проверка на равенство . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
4.4.5. Удаление элементов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
4.4.6. Перебор элементов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
4.4.7. Пользовательские типы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
4.5. Строки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
4.5.1. Кодовые точки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
4.5.2. Кодировки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
4.5.3. Знаковые типы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
4.5.4. Массивы знаков + бонусы = строки . . . . . . . . . . . . . . . . . . . . . 160
4.6. Опасный собрат массива – указатель . . . . . . . . . . . . . . . . . . . . . . . . 164
4.7. Итоги и справочник . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Глава 5. Данные и функции. Функциональный стиль . . . . . . . . . . . . . . . . . 170
5.1. Написание и модульное тестирование простой функции . . . . . . . 171
5.2. Соглашения о передаче аргументов и классы памяти . . . . . . . . . . 173
5.2.1. Параметры и возвращаемые значения, переданные
по ссылке (с ключевым словом ref) . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
5.2.2. Входные параметры (с ключевым словом in) . . . . . . . . . . . . . 175
5.2.3. Выходные параметры (с ключевым словом out) . . . . . . . . . . . 176
5.2.4. Ленивые аргументы (с ключевым словом lazy) . . . . . . . . . . . . 177
5.2.5. Статические данные (с ключевым словом static) . . . . . . . . . . 178
5.3. Параметры типов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
5.4. Ограничения сигнатуры . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
5.5. Перегрузка . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .183
5.5.1. Отношение частичного порядка на множестве функций . . . 185
5.5.2. Кроссмодульная перегрузка . . . . . . . . . . . . . . . . . . . . . . . . . . .188
5.6. Функции высокого порядка. Функциональные литералы . . . . . .190


8 Оглавление

5.6.1. Функциональные литералы
против литералов делегатов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
5.7. Вложенные функции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
5.8. Замыкания . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
5.8.1. Так, это работает… Стоп, не должно…
Нет, все же работает! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .196
5.9. Не только массивы. Диапазоны. Псевдочлены . . . . . . . . . . . . . . . . 197
5.9.1. Псевдочлены и атрибут @property . . . . . . . . . . . . . . . . . . . . . .199
5.9.2. Свести – но не к абсурду . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .201
5.10. Функции с переменным числом аргументов . . . . . . . . . . . . . . . . .203
5.10.1. Гомогенные функции
с переменным числом аргументов . . . . . . . . . . . . . . . . . . . . . . . . . . . .203
5.10.2. Гетерогенные функции
с переменным числом аргументов . . . . . . . . . . . . . . . . . . . . . . . . . . . .205
5.10.3. Гетерогенные функции с переменным числом
аргументов. Альтернативный подход . . . . . . . . . . . . . . . . . . . . . . . . .209
5.11. Атрибуты функций . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
5.11.1. Чистые функции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
5.11.2. Атрибут nothrow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
5.12. Вычисления во время компиляции . . . . . . . . . . . . . . . . . . . . . . . . . 218
Глава 6. Классы. Объектно-ориентированный стиль . . . . . . . . . . . . . . . . . .225
6.1. Классы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .225
6.2. Имена объектов – это ссылки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .227
6.3. Жизненный цикл объекта . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
6.3.1. Конструкторы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .232
6.3.2. Делегирование конструкторов . . . . . . . . . . . . . . . . . . . . . . . . .233
6.3.3. Алгоритм построения объекта . . . . . . . . . . . . . . . . . . . . . . . . .235
6.3.4. Уничтожение объекта и освобождение памяти . . . . . . . . . . .237
6.3.5. Алгоритм уничтожения объекта . . . . . . . . . . . . . . . . . . . . . . .237
6.3.6. Стратегия освобождения памяти . . . . . . . . . . . . . . . . . . . . . . .239
6.3.7. Статические конструкторы и деструкторы . . . . . . . . . . . . . . .242
6.4. Методы и наследование . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .244
6.4.1. Терминологический «шведский стол» . . . . . . . . . . . . . . . . . . .245
6.4.2. Наследование – это порождение подтипа.
Статический и динамический типы . . . . . . . . . . . . . . . . . . . . . . . . . .246
6.4.3. Переопределение – только по желанию . . . . . . . . . . . . . . . . . . 247
6.4.4. Вызов переопределенных методов . . . . . . . . . . . . . . . . . . . . . .248
6.4.5. Ковариантные возвращаемые типы . . . . . . . . . . . . . . . . . . . . .249
6.5. Инкапсуляция на уровне классов с помощью
статических членов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
6.6. Сдерживание расширяемости с помощью
финальных методов. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
6.6.1. Финальные классы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .253
6.7. Инкапсуляция . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .254
6.7.1. private . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .255
6.7.2. package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .255


Оглавление 9

6.7.3. protected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .255
6.7.4. public . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .256
6.7.5. export . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .256
6.7.6. Сколько инкапсуляции? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
6.8. Основа безраздельной власти . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .260
6.8.1. string toString() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .260
6.8.2. size_t toHash() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .261
6.8.3. bool opEquals(Object rhs). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .261
6.8.4. int opCmp(Object rhs) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .265
6.8.5. static Object factory (string className) . . . . . . . . . . . . . . . . . .266
6.9. Интерфейсы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .268
6.9.1. Идея невиртуальных интерфейсов (NVI) . . . . . . . . . . . . . . . .269
6.9.2. Защищенные примитивы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
6.9.3. Избирательная реализация . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
6.10. Абстрактные классы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
6.11. Вложенные классы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
6.11.1. Вложенные классы в функциях . . . . . . . . . . . . . . . . . . . . . . .280
6.11.2. Статические вложенные классы . . . . . . . . . . . . . . . . . . . . . . .281
6.11.3. Анонимные классы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .282
6.12. Множественное наследование . . . . . . . . . . . . . . . . . . . . . . . . . . . . .283
6.13. Множественное порождение подтипов . . . . . . . . . . . . . . . . . . . . . .287
6.13.1. Переопределение методов в сценариях
множественного порождения подтипов . . . . . . . . . . . . . . . . . . . . . . .288
6.14. Параметризированные классы и интерфейсы . . . . . . . . . . . . . . . .290
6.14.1. И снова гетерогенная трансляция. . . . . . . . . . . . . . . . . . . . . .292
6.15. Переопределение аллокаторов и деаллокаторов . . . . . . . . . . . . . .294
6.16. Объекты scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .296
6.17. Итоги . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .299
Глава 7. Другие пользовательские типы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .301
7.1. Структуры . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .302
7.1.1. Семантика копирования . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .303
7.1.2. Передача объекта-структуры в функцию . . . . . . . . . . . . . . . .304
7.1.3. Жизненный цикл объекта-структуры . . . . . . . . . . . . . . . . . . .305
7.1.4. Статические конструкторы и деструкторы . . . . . . . . . . . . . . . 316
7.1.5. Методы. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
7.1.6. Статические внутренние элементы . . . . . . . . . . . . . . . . . . . . . . 321
7.1.7. Спецификаторы доступа . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .322
7.1.8. Вложенность структур и классов . . . . . . . . . . . . . . . . . . . . . . .323
7.1.9. Структуры, вложенные в функции . . . . . . . . . . . . . . . . . . . . . .324
7.1.10. Порождение подтипов в случае структур.
Атрибут @disable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .325
7.1.11. Взаимное расположение полей. Выравнивание . . . . . . . . . .328
7.2. Объединение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .331
7.3. Перечисляемые значения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .334
7.3.1. Перечисляемые типы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .336
7.3.2. Свойства перечисляемых типов . . . . . . . . . . . . . . . . . . . . . . . .337


10 Оглавление

7.4. alias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .338
7.5. Параметризированные контексты (конструкция template) . . . . .341
7.5.1. Одноименные шаблоны . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .343
7.5.2. Параметр шаблона this . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .344
7.6. Инъекции кода с помощью конструкции mixin template . . . . . . .345
7.6.1. Поиск идентификаторов внутри mixin. . . . . . . . . . . . . . . . . . . 347
7.7. Итоги . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .348
Глава 8. Квалификаторы типа . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .349
8.1. Квалификатор immutable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .350
8.1.1. Транзитивность . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
8.2. Составление типов с помощью immutable . . . . . . . . . . . . . . . . . . . .353
8.3. Неизменяемые параметры и методы . . . . . . . . . . . . . . . . . . . . . . . . .354
8.4. Неизменяемые конструкторы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .356
8.5. Преобразования с участием immutable . . . . . . . . . . . . . . . . . . . . . . . 357
8.6. Квалификатор const . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .359
8.7. Взаимодействие между const и immutable . . . . . . . . . . . . . . . . . . . .361
8.8. Распространение квалификатора с параметра на результат . . . . .362
8.9. Итоги . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .363
Глава 9. Обработка ошибок . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .364
9.1. Порождение и обработка исключительных ситуаций . . . . . . . . . .364
9.2. Типы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .366
9.3. Блоки finally . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .369
9.4. Функции, не порождающие исключения (nothrow),
и особая природа класса Throwable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
9.5. Вторичные исключения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
9.6. Раскрутка стека и код, защищенный от исключений . . . . . . . . . . 373
9.7. Неперехваченные исключения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
Глава 10. Контрактное программирование . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
10.1. Контракты . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
10.2. Утверждения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .381
10.3. Предусловия . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .382
10.4. Постусловия . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .384
10.5. Инварианты . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .385
10.6. Пропуск проверок контрактов. Итоговые сборки . . . . . . . . . . . . .389
10.6.1. enforce – это не (совсем) assert . . . . . . . . . . . . . . . . . . . . . . . . .389
10.6.2. assert(false) – останов программы . . . . . . . . . . . . . . . . . . . . .391
10.7. Контракты – не для очистки входных данных . . . . . . . . . . . . . . .392
10.8. Наследование . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .394
10.8.1. Наследование и предусловия . . . . . . . . . . . . . . . . . . . . . . . . . .394
10.8.2. Наследование и постусловия . . . . . . . . . . . . . . . . . . . . . . . . . .396
10.8.3. Наследование и инварианты . . . . . . . . . . . . . . . . . . . . . . . . . .398
10.9. Контракты и интерфейсы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .398


Оглавление 11

Глава 11. Расширение масштаба . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401
11.1. Пакеты и модули . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401
11.1.1. Объявления import . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .403
11.1.2. Базовые пути поиска модулей . . . . . . . . . . . . . . . . . . . . . . . . .405
11.1.3. Поиск имен . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .406
11.1.4. Объявления public import . . . . . . . . . . . . . . . . . . . . . . . . . . . . .409
11.1.5. Объявления static import . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410
11.1.6. Избирательные включения . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
11.1.7. Включения с переименованием . . . . . . . . . . . . . . . . . . . . . . . . 412
11.1.8. Объявление модуля . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414
11.1.9. Резюме модулей . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
11.2. Безопасность . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
11.2.1. Определенное и неопределенное поведение . . . . . . . . . . . . . . 419
11.3.2. Атрибуты @safe, @trusted и @system . . . . . . . . . . . . . . . . . .420
11.3. Конструкторы и деструкторы модулей . . . . . . . . . . . . . . . . . . . . . .422
11.3.1. Порядок выполнения в рамках модуля . . . . . . . . . . . . . . . . .423
11.3.2. Порядок выполнения
при участии нескольких модулей . . . . . . . . . . . . . . . . . . . . . . . . . . . .423
11.4. Документирующие комментарии . . . . . . . . . . . . . . . . . . . . . . . . . .424
11.5. Взаимодействие с C и C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .425
11.5.1. Взаимодействие с классами C++ . . . . . . . . . . . . . . . . . . . . . . .426
11.6. Ключевое слово deprecated . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .427
11.7. Объявления версий . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .427
11.8. Отладочные объявления . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .429
11.9. Стандартная библиотека D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .429
11.10. Встроенный ассемблер . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
11.10.1. Архитектура x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .432
11.10.2. Архитектура x86-64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .435
11.10.3. Разделение на версии . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .436
11.10.4. Соглашения о вызовах . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .437
11.10.5. Рациональность . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .441
Глава 12. Перегрузка операторов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .443
12.1. Перегрузка операторов в D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .445
12.2. Перегрузка унарных операторов . . . . . . . . . . . . . . . . . . . . . . . . . . .445
12.2.1. Объединение определений операторов с помощью
выражения mixin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .446
12.2.2. Постфиксный вариант операторов увеличения
и уменьшения на единицу . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
12.2.3. Перегрузка оператора cast . . . . . . . . . . . . . . . . . . . . . . . . . . . .448
12.2.4. Перегрузка тернарной условной операции и ветвления . . . .449
12.3. Перегрузка бинарных операторов . . . . . . . . . . . . . . . . . . . . . . . . . .450
12.3.1. Перегрузка операторов в квадрате . . . . . . . . . . . . . . . . . . . . . 451
12.3.2. Коммутативность . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
12.4. Перегрузка операторов сравнения . . . . . . . . . . . . . . . . . . . . . . . . . .453
12.5. Перегрузка операторов присваивания . . . . . . . . . . . . . . . . . . . . . .454


12 Оглавление

12.6. Перегрузка операторов индексации . . . . . . . . . . . . . . . . . . . . . . . .456
12.7. Перегрузка операторов среза . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .458
12.8. Оператор $ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .458
12.9. Перегрузка foreach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .459
12.9.1. foreach с примитивами перебора . . . . . . . . . . . . . . . . . . . . . . .459
12.9.2. foreach с внутренним перебором . . . . . . . . . . . . . . . . . . . . . . .460
12.10. Определение перегруженных операторов в классах . . . . . . . . . .462
12.11. Кое-что из другой оперы: opDispatch . . . . . . . . . . . . . . . . . . . . . .463
12.11.1. Динамическое диспетчирование с opDispatch . . . . . . . . . .465
12.12. Итоги и справочник . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .466
Глава 13. Параллельные вычисления . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .469
13.1. Революция в области параллельных вычислений . . . . . . . . . . . . 470
13.2. Краткая история механизмов разделения данных . . . . . . . . . . . . 473
13.3. Смотри, мам, никакого разделения (по умолчанию) . . . . . . . . . . 477
13.4. Запускаем поток . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479
13.4.1. Неизменяемое разделение . . . . . . . . . . . . . . . . . . . . . . . . . . . .480
13.5. Обмен сообщениями между потоками . . . . . . . . . . . . . . . . . . . . . .481
13.6. Сопоставление по шаблону с помощью receive . . . . . . . . . . . . . . .483
13.6.1. Первое совпадение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .485
13.6.2. Соответствие любому сообщению . . . . . . . . . . . . . . . . . . . . . .486
13.7. Копирование файлов – с выкрутасом . . . . . . . . . . . . . . . . . . . . . . .486
13.8. Останов потока . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .488
13.9. Передача нештатных сообщений . . . . . . . . . . . . . . . . . . . . . . . . . . .490
13.10. Переполнение почтового ящика. . . . . . . . . . . . . . . . . . . . . . . . . . .492
13.11. Квалификатор типа shared . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .493
13.11.1. Сюжет усложняется:
квалификатор shared транзитивен . . . . . . . . . . . . . . . . . . . . . . . . . . .494
13.12. Операции с разделяемыми данными и их применение . . . . . . .495
13.12.1. Последовательная целостность разделяемых данных . . . .496
13.13. Синхронизация на основе блокировок через
синхронизированные классы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .497
13.14. Типизация полей в синхронизированных классах . . . . . . . . . . .502
13.14.1. Временная защита == нет утечкам . . . . . . . . . . . . . . . . . . . .503
13.14.2. Локальная защита == разделение хвостов . . . . . . . . . . . . .504
13.14.3. Принудительные идентичные мьютексы . . . . . . . . . . . . . .506
13.14.4. Фильм ужасов: приведение от shared . . . . . . . . . . . . . . . . . .507
13.15. Взаимоблокировки и инструкция synchronized . . . . . . . . . . . . .508
13.16. Кодирование без блокировок с помощью
разделяемых классов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510
13.16.1. Разделяемые классы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511
13.16.2. Пара структур без блокировок . . . . . . . . . . . . . . . . . . . . . . . 512
13.17. Статические конструкторы и потоки . . . . . . . . . . . . . . . . . . . . . . . 515
13.18. Итоги . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517
Литература. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
Алфавитный указатель . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .523