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