diff --git a/03-инструкция/README.md b/03-инструкция/README.md index a314023..f2d409e 100644 --- a/03-инструкция/README.md +++ b/03-инструкция/README.md @@ -386,6 +386,8 @@ Error: final switch statement must handle all values Инструкция `final switch` требует, чтобы все значения типа `enum` были явно обработаны. Метки с интервалами вида `case ‹в1›: .. case ‹в2›:`, а также метку `default`: использовать запрещено. +[Исходный код](src/chapter-3-6/) + [В начало ⮍](#3-6-инструкция-final-switch) [Наверх ⮍](#3-инструкции) ## 3.7. Циклы @@ -473,6 +475,8 @@ void main() } ``` +[Исходный код](src/chapter-3-7-4/) + [В начало ⮍](#3-7-4-инструкция-foreach-цикл-просмотра) [Наверх ⮍](#3-инструкции) ### 3.7.5. Цикл просмотра для работы с массивами @@ -576,6 +580,8 @@ array['Луна'] = 1.283; - *Изменение размера массива*. Цикл повторяется, пока не будет просмотрено столько элементов массива, сколько в нем было до входа в цикл. Возможно, в результате изменения размера массив будет перемещен в другую область памяти; в этом случае последующее изменение массива не видно во время итерации, а также последующие изменения, вызванные во время самой итерации, не отразятся на массиве. Использовать такую технику не рекомендуется, поскольку правила перемещения массива в памяти зависят от реализации. - *Освобождение выделенной под массив памяти (полное или частичное; в последнем случае говорят о «сжатии» массива) с помощью низкоуровневых функций управления памятью*. Желая получить полный контроль и достичь максимальной эффективности, вы не пожалели времени на изучение низкоуровневого управления памятью по документации к своей реализации языка. Все, что можно предположить: 1) вы знаете, что творите, и 2) не скучно с вами лишь тому, кто написал собственный сборщик мусора. +[Исходный код](src/chapter-3-7-5/) + [В начало ⮍](#3-7-5-цикл-просмотра-для-работы-с-массивами) [Наверх ⮍](#3-инструкции) ### 3.7.6. Инструкции continue и break @@ -741,6 +747,8 @@ with (‹выр1›) with (‹выр2›) ... with (‹вырn›) ‹инстр При использовании вложенных инструкций `with` нет угрозы неопределенности, так как язык запрещает во внутренней инструкции `with` перекрывать идентификатор, определенный во внешней инструкции `with`. В двух словах: в D локальному идентификатору запрещено перекрывать другой локальный идентификатор. +[Исходный код](src/chapter-3-9/) + [В начало ⮍](#3-9-инструкция-with) [Наверх ⮍](#3-инструкции) ## 3.10. Инструкция return @@ -788,6 +796,8 @@ finally ‹инструкцияf› Инструкция `goto` (см. раздел 3.8) не может совершить переход внутрь инструкций `‹инструкция›`, `‹инструкция1›`, `...`, `‹инструкцияn›` и `‹инструкцияf›`, кроме случая, когда `goto` находится внутри самой инструкции. +[Исходный код](src/chapter-3-11/) + [В начало ⮍](#3-11-обработка-исключительных-ситуаций) [Наверх ⮍](#3-инструкции) ## 3.12. Инструкция mixin @@ -854,6 +864,8 @@ mixin(import("widget.d")); Выражение `import` считывает текст файла `widget.d` в строковый литерал, который выражение `mixin` тут же преобразует в код. Используйте этот трюк, только если действительно считаете, что без него ваша честь хакера поставлена на карту. +[Исходный код](src/chapter-3-12/) + [В начало ⮍](#3-12-инструкция-mixin) [Наверх ⮍](#3-инструкции) ## 3.13. Инструкция scope @@ -1043,6 +1055,8 @@ void transactionalCreate(string filename) Большой плюс такого стиля программирования состоит в том, что весь код обработки ошибок собран в начале функции `transactionalCreate` и никак не затрагивает основной код. При всей своей простоте функция `transactionalCreate` очень надежна: вы получаете или готовый файл, или временный файл-фрагмент, но только не «битый» файл, который кажется нормальным. +[Исходный код](src/chapter-3-13/) + [В начало ⮍](#3-13-инструкция-scope) [Наверх ⮍](#3-инструкции) ## 3.14. Инструкция synchronized diff --git a/03-инструкция/src/chapter-3-11/app.d b/03-инструкция/src/chapter-3-11/app.d new file mode 100644 index 0000000..e4e8253 --- /dev/null +++ b/03-инструкция/src/chapter-3-11/app.d @@ -0,0 +1,29 @@ +/** + * 1. Объявите класс, который наследуется от Exception. + * 2. Создайте конструктор, который принимает, как минимум, два параметра: string file и + * size_t line, со значениями по умолчанию __FILE__ и __LINE__ соответственно. + * 3. Попросите конструктора переслать аргументы конструктору исключения (super). + * 4. Используйте свое исключение. + */ + +class MyException : Exception +{ + this (string message, string file = __FILE__, size_t line = __LINE__, Throwable next = null) + { + super(message, file, line, next); + } +} + +void main() +{ + import std.stdio; + + try + { + throw new MyException("message here"); + } + catch(MyException e) + { + writeln("caught ", e); + } +} diff --git a/03-инструкция/src/chapter-3-12/app.d b/03-инструкция/src/chapter-3-12/app.d new file mode 100644 index 0000000..e4e8253 --- /dev/null +++ b/03-инструкция/src/chapter-3-12/app.d @@ -0,0 +1,29 @@ +/** + * 1. Объявите класс, который наследуется от Exception. + * 2. Создайте конструктор, который принимает, как минимум, два параметра: string file и + * size_t line, со значениями по умолчанию __FILE__ и __LINE__ соответственно. + * 3. Попросите конструктора переслать аргументы конструктору исключения (super). + * 4. Используйте свое исключение. + */ + +class MyException : Exception +{ + this (string message, string file = __FILE__, size_t line = __LINE__, Throwable next = null) + { + super(message, file, line, next); + } +} + +void main() +{ + import std.stdio; + + try + { + throw new MyException("message here"); + } + catch(MyException e) + { + writeln("caught ", e); + } +} diff --git a/03-инструкция/src/chapter-3-13/app.d b/03-инструкция/src/chapter-3-13/app.d new file mode 100644 index 0000000..9b1934b --- /dev/null +++ b/03-инструкция/src/chapter-3-13/app.d @@ -0,0 +1,9 @@ +void main() +{ + import std.stdio; + + scope(exit) writeln("Running scope exit"); // Выполнится самая последняя + scope(success) writeln("Running scope success"); // Выполнится самая первая + return; + scope(exit) writeln("This is never run since the function returned before it was registered."); // Не выполнится +} diff --git a/03-инструкция/src/chapter-3-6/app.d b/03-инструкция/src/chapter-3-6/app.d new file mode 100644 index 0000000..36f9887 --- /dev/null +++ b/03-инструкция/src/chapter-3-6/app.d @@ -0,0 +1,34 @@ +import std.stdio; +import std.conv; + +enum Berries { strawberry, blackberry, blueberry } + +string[] names = [ + "Клубника", + "Ежевика", + "Черника" + ]; + +void printBerry(Berries b) +{ + final switch (b) + { + case b.strawberry: + writeln(names[b.strawberry]); + break; + case b.blackberry: + writeln(names[b.blackberry]); + break; + case b.blueberry: + writeln(names[b.blueberry]); + break; + } +} + +void main() +{ + int berry; + + readf("%s\n", berry); + printBerry(to!Berries(berry)); +} diff --git a/03-инструкция/src/chapter-3-7-4/app.d b/03-инструкция/src/chapter-3-7-4/app.d new file mode 100644 index 0000000..ef4d6e0 --- /dev/null +++ b/03-инструкция/src/chapter-3-7-4/app.d @@ -0,0 +1,17 @@ +import std.math, std.stdio; + +void main() +{ + foreach (float elem; 1.0 .. 100.0) + { + writeln(log(elem)); // По­лу­ча­ет ло­га­рифм с оди­нар­ной точ­но­стью + } + foreach (double elem; 1.0 .. 100.0) + { + writeln(log(elem)); // Двой­ная точ­ность + } + foreach (elem; 1.0 .. 100.0) + { + writeln(log(elem)); // То же са­мое + } +} diff --git a/03-инструкция/src/chapter-3-7-5/app.d b/03-инструкция/src/chapter-3-7-5/app.d new file mode 100644 index 0000000..6813bd9 --- /dev/null +++ b/03-инструкция/src/chapter-3-7-5/app.d @@ -0,0 +1,23 @@ +import std.stdio; + +void print(double[string] map) +{ + foreach (i, e; map) + { + writefln("array['%s'] = %s;", i, e); + } +} + +void main() +{ + float[] arr = [ 1.0, 2.5, 4.0 ]; + + foreach (ref float elem; arr) + { + elem *= 2; // Без про­блем + } + + writeln(arr); + + print(["Луна": 1.283, "Солнце": 499.307, "Проксима Центавра": 133_814_298.759]); +} diff --git a/03-инструкция/src/chapter-3-9/app.d b/03-инструкция/src/chapter-3-9/app.d new file mode 100644 index 0000000..e64f838 --- /dev/null +++ b/03-инструкция/src/chapter-3-9/app.d @@ -0,0 +1,24 @@ +import std.math, std.stdio; + +struct Point +{ + double x, y; + double norm() + { + return sqrt(x * x + y * y); + } +} + +void main() +{ + Point p; + int z; + + with (p) + { + x = 3; // При­сваи­ва­ет зна­че­ние по­лю p.x + p.y = 4; // Хо­ро­шо, что все еще мож­но яв­но ис­поль­зо­вать p + writeln(norm()); // Вы­во­дит зна­че­ние по­ля p.norm, то есть 5 + z = 1; // По­ле z ос­та­лось ви­ди­мым + } +}