1.3
This commit is contained in:
parent
2b58cd0390
commit
b2bfe5c7a1
|
@ -1,8 +1,8 @@
|
||||||
# 1. Знакомство с языком D
|
# 1. Знакомство с языком D
|
||||||
|
|
||||||
- [1.1. Числа и выражения](#11-числа-и-выражения)
|
- [1.1. Числа и выражения](#1-1-числа-и-выражения)
|
||||||
- [1.2. Инструкции](#12-инструкции)
|
- [1.2. Инструкции](#1-2-инструкции)
|
||||||
- [1.3. Основы работы с функциями]()
|
- [1.3. Основы работы с функциями](#1-3-основы-работы-с-функциями)
|
||||||
- 1.4. Массивы и ассоциативные массивы
|
- 1.4. Массивы и ассоциативные массивы
|
||||||
- [1.4.1. Работа со словарем]()
|
- [1.4.1. Работа со словарем]()
|
||||||
- [1.4.2. Получение среза массива. Функции с обобщенными типами параметров. Тесты модулей]()
|
- [1.4.2. Получение среза массива. Функции с обобщенными типами параметров. Тесты модулей]()
|
||||||
|
@ -178,4 +178,45 @@ if (‹выражение›) ‹инструкция1› else ‹инструк
|
||||||
|
|
||||||
Чисто теоретический вывод, известный как принцип структурного программирования, гласит, что все алгоритмы можно реализовать с помощью составных инструкций, `if`-проверок и циклов а-ля `for` и `foreach`. Разумеется, любой адекватный язык (как и D) предлагает гораздо больше, но мы пока постановим, что с нас довольно и этих инструкций, и двинемся дальше.
|
Чисто теоретический вывод, известный как принцип структурного программирования, гласит, что все алгоритмы можно реализовать с помощью составных инструкций, `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) – обозначение пути к компилятору или интерпретатору в виде `#!/путь/к/программе`. – *Прим. пер.*
|
[^1]: «Shebang» (от shell bang: shell – консоль, bang – восклицательный знак), или «shabang» (# – sharp) – обозначение пути к компилятору или интерпретатору в виде `#!/путь/к/программе`. – *Прим. пер.*
|
||||||
|
[^2]: В этой книге под «параметром» понимается значение, используемое внутри функции, а под «аргументом» – значение, передаваемое в функцию извне.
|
||||||
|
|
Loading…
Reference in New Issue