From b2bfe5c7a11f3908beae7854cda9a13d17b6f763 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 22 Jan 2023 11:36:37 +0300 Subject: [PATCH] 1.3 --- 01-знакомство-с-языком-d/README.md | 47 ++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/01-знакомство-с-языком-d/README.md b/01-знакомство-с-языком-d/README.md index 78f1245..56cc1f2 100644 --- a/01-знакомство-с-языком-d/README.md +++ b/01-знакомство-с-языком-d/README.md @@ -1,8 +1,8 @@ # 1. Знакомство с языком D -- [1.1. Числа и выражения](#11-числа-и-выражения) -- [1.2. Инструкции](#12-инструкции) -- [1.3. Основы работы с функциями]() +- [1.1. Числа и выражения](#1-1-числа-и-выражения) +- [1.2. Инструкции](#1-2-инструкции) +- [1.3. Основы работы с функциями](#1-3-основы-работы-с-функциями) - 1.4. Массивы и ассоциативные массивы - [1.4.1. Работа со словарем]() - [1.4.2. Получение среза массива. Функции с обобщенными типами параметров. Тесты модулей]() @@ -178,4 +178,45 @@ if (‹выражение›) ‹инструкция1› else ‹инструк Чисто теоретический вывод, известный как принцип структурного программирования, гласит, что все алгоритмы можно реализовать с помощью составных инструкций, `if`-проверок и циклов а-ля `for` и `foreach`. Разумеется, любой адекватный язык (как и D) предлагает гораздо больше, но мы пока постановим, что с нас довольно и этих инструкций, и двинемся дальше. +## 1.3. Основы работы с функциями + +Оставим пока в стороне обязательное определение функции `main` и посмотрим, как определяются другие функции на D. Определение функции соответствует модели, характерной и для других Алгол-подобных языков: сначала пишется возвращаемый тип, потом имя функции и, наконец, заключенный в круглые скобки список формальных аргументов, разделенных запятыми. Например, определение функции с именем `pow`, которая принимает значения типа `double` и `int`, а возвращает `double`, записывается так: + +```d +double pow(double base, int exponent) +{ + ... +} +``` + +Каждый параметр функции (`base` и `exponent` в данном примере) кроме типа может иметь необязательный ***класс памяти*** (***storage class***), определяющий способ передачи аргумента в функцию при ее вызове[^2]. + +По умолчанию аргументы передаются в `pow` по значению. Если перед типом параметра указан класс памяти `ref`, то параметр привязывается напрямую к входному аргументу, так что изменение параметра непосредственно отражается на значении, полученном извне. Например: + +```d +import std.stdio; + +void fun(ref uint x, double y) +{ + x = 42; + y = 3.14; +} + +void main() +{ + uint a = 1; + double b = 2; + fun(a, b); + writeln(a, " ", b); +} + +``` + +Эта программа печатает `42 2`, потому что `x` определен как `ref uint`, то есть когда значение присваивается x, на самом деле операция проводится с `a`. С другой стороны, присваивание значения переменной `y` никак не скажется на `b`, поскольку `y` – это внутренняя копия в распоряжении функции `fun`. + +Последние «украшения», которые мы обсудим в этом кратком введении, – это `in` и `out`. Попросту говоря, `in` – данное функцией «обещание» только смотреть на параметр, не «трогая» его. Указание `out` в определении параметра функции действует сходно с `ref`, с той поправкой, что параметр принудительно инициализируется своим значением по умолчанию при «входе» в функцию. (Для каждого типа `T` определено начальное значение, обозначаемое как `T.init`. Пользовательские типы могут определять собственное значение по умолчанию.) + +О функциях можно еще долго рассказывать. Можно передавать функции другим функциям, встраивать одну в другую, разрешать функции сохранять свою локальную среду (полнофункциональная синтаксическая клауза), создавать анонимные функции (лямбда-функции), с удобством манипулировать ими и еще множество дополнительных «вкусностей». Со временем мы доберемся до каждой из них. + [^1]: «Shebang» (от shell bang: shell – консоль, bang – восклицательный знак), или «shabang» (# – sharp) – обозначение пути к компилятору или интерпретатору в виде `#!/путь/к/программе`. – *Прим. пер.* +[^2]: В этой книге под «параметром» понимается значение, используемое внутри функции, а под «аргументом» – значение, передаваемое в функцию извне.