2.3.5.-2.3.6

This commit is contained in:
Alexander Zhirov 2023-01-22 19:15:40 +03:00
parent 8ed1cd13fa
commit 79765a3d33
1 changed files with 55 additions and 7 deletions

View File

@ -22,13 +22,13 @@
- [2.3.4.2. Выражение mixin](#2-3-4-2-выражение-mixin) - [2.3.4.2. Выражение mixin](#2-3-4-2-выражение-mixin)
- [2.3.4.3. Выражения is](#2-3-4-3-выражения-is) - [2.3.4.3. Выражения is](#2-3-4-3-выражения-is)
- [2.3.4.4. Выражения в круглых скобках](#2-3-4-4-выражения-в-круглых-скобках) - [2.3.4.4. Выражения в круглых скобках](#2-3-4-4-выражения-в-круглых-скобках)
- [2.3.5. Постфиксные операции]() - [2.3.5. Постфиксные операции](#2-3-5-постфиксные-операции)
- [2.3.5.1. Доступ ко внутренним элементам]() - [2.3.5.1. Доступ ко внутренним элементам](#2-3-5-1-доступ-ко-внутренним-элементам)
- [2.3.5.2. Увеличение и уменьшение на единицу]() - [2.3.5.2. Увеличение и уменьшение на единицу](#2-3-5-2-увеличение-и-уменьшение-на-единицу)
- [2.3.5.3. Вызов функции]() - [2.3.5.3. Вызов функции](#2-3-5-3-вызов-функции)
- [2.3.5.4. Индексация]() - [2.3.5.4. Индексация](#2-3-5-4-индексация)
- [2.3.5.5. Срезы массивов]() - [2.3.5.5. Срезы массивов](#2-3-5-5-срезы-массивов)
- [2.3.5.6. Создание вложенного класса]() - [2.3.5.6. Создание вложенного класса](#2-3-5-6-создание-вложенного-класса)
- [2.3.6. Унарные операции]() - [2.3.6. Унарные операции]()
- [2.3.6.1. Выражение new]() - [2.3.6.1. Выражение new]()
- [2.3.6.2. Получение адреса и разыменование]() - [2.3.6.2. Получение адреса и разыменование]()
@ -719,6 +719,54 @@ bool
[В начало ⮍](#2-3-4-4-выражения-в-круглых-скобках) [Наверх ⮍](#2-основные-типы-данных-выражения) [В начало ⮍](#2-3-4-4-выражения-в-круглых-скобках) [Наверх ⮍](#2-основные-типы-данных-выражения)
### 2.3.5. Постфиксные операции
#### 2.3.5.1. Доступ ко внутренним элементам
Оператор доступа ко внутренним элементам `a.b` предоставляет доступ к элементу с именем `b`, расположенному внутри объекта или типа `a`. Если `a` сложное значение или сложный тип, допустимо заключить его в круглые скобки. В качестве `b` также может выступать выражение с ключевым словом `new` (см. главу 6).
[В начало ⮍](#2-3-5-1-доступ-ко-внутренним-элементам) [Наверх ⮍](#2-основные-типы-данных-выражения)
#### 2.3.5.2. Увеличение и уменьшение на единицу
Постфиксный вариант операции увеличения и уменьшения на единицу (`значение++` и `значение--` соответственно) определен для всех числовых типов и указателей и имеет тот же смысл, что и одноименная операция в C и C++: применение этой операции увеличивает или уменьшает на единицу `значение` (которое должно быть l-значением), возвращая копию этого значения до его изменения. (Аналогичный префиксный вариант операции увеличения и уменьшения на единицу описан в разделе 2.3.6.3.)
[В начало ⮍](#2-3-5-2-увеличение-и-уменьшение-на-единицу) [Наверх ⮍](#2-основные-типы-данных-выражения)
#### 2.3.5.3. Вызов функции
Уже знакомый оператор вызова функции `fun()` инициирует выполнение кода функции `fun`. Синтаксис `fun(<список аргументов, разделенных запятыми>)` передает в тело `fun` список аргументов. Все аргументы вычисляются слева направо перед вызовом `fun`. Количество и типы значений в списке аргументов должны соответствовать количеству и типам формальных параметров. Если функция определена с атрибутом `@property`, то указание просто имени функции эквивалентно вызову этой функции без аргументов. Обычно `fun` это имя функции, указанное в ее определении, но может быть и функциональным литералом (см. раздел 2.2.7) или выражением, возвращающим указатель на функцию или `delegate`. Подробно функции описаны в главе 5.
[В начало ⮍](#2-3-5-3-вызов-функции) [Наверх ⮍](#2-основные-типы-данных-выражения)
#### 2.3.5.4. Индексация
Выражение `arr[i]` позволяет получить доступ к `i`-му элементу массива или ассоциативного массива `arr` (элементы массива индексируются начиная с 0). Если массив неассоциативный, то значение `i` должно быть целым. Иначе значение `i` должно иметь тип, который может быть неявно преобразован к типу ключа массива `arr`. Если индексирующее выражение находится слева от оператора присваивания (например, `arr[i] = e`) и `arr` ассоциативный массив, выполняется вставка элемента в массив, если его там не было. Иначе если i относится к элементу, которого нет в массиве `arr`, выражение порождает исключение типа `RangeError`. В качестве `arr` и `i` также могут выступать указатель и целое соответственно. Операции индексации с помощью указателей автоматически не проверяются. В некоторых режимах сборки (небезопасные итоговые сборки; см. раздел 4.1.2) отменяется проверка границ и в случае неассоциативных массивов.
[В начало ⮍](#2-3-5-4-индексация) [Наверх ⮍](#2-основные-типы-данных-выражения)
#### 2.3.5.5. Срезы массивов
Если `arr` линейный (неассоциативный) массив, выражение `arr[i .. j]` возвращает массив, ссылающийся на интервал внутри `arr` от `i`-го до `j`-го элемента (не включая последний). Значения `i` и `j`, отмечающие границы среза, должны допускать неявное преобразование в целое. Выражение `arr[]` позволяет адресовать срез массива величиной в целый массив `arr`. Данные не копируются «по-настоящему», поэтому изменение среза массива влечет к изменению содержимого исходного массива `arr`. Например:
```d
int[] a = new int[5]; // Создать массив из пяти целых чисел
int[] b = a[3 .. 5]; // b ссылается на два последних элемента a
b[0] = 1;
b[1] = 3;
assert(a == [ 0, 0, 0, 1, 3 ]); // a был изменен
```
Если `i > j` или `j > a.length`, генерируется исключение типа `RangeError`. Иначе если `i == j`, будет возвращен пустой массив. В качестве `arr` в выражении `arr[i .. j]` можно использовать указатель. В этом случае будет возвращен массив, отражающий область памяти начиная с адреса `arr + i` до `arr + j` (не включая элемент с адресом `arr + j`). Если `i > j`, генерируется ошибка `RangeError`, иначе при получении среза указателя границы не проверяются. И снова в некоторых режимах сборки (небезопасные итоговые сборки, см. раздел 4.1.2) все проверки границ при получении срезов могут быть отключены.
[В начало ⮍](#2-3-5-5-срезы-массивов) [Наверх ⮍](#2-основные-типы-данных-выражения)
#### 2.3.5.6. Создание вложенного класса
Выражение вида `a.new T`, где a значение типа `class`, создает объект типа `T`, чье определение вложено в определение `a`. Что-то непонятно? Это потому что мы еще не определили ни классы, ни вложенные классы, и даже сами выражения `new` пока не рассмотрели. Определение выражения `new` уже совсем близко (в разделе 2.3.6.1), а чтобы познакомиться с определениями классов и вложенных классов, придется подождать до главы 6 (точнее до раздела 6.11). А до тех пор считайте этот раздел просто заглушкой, необходимой для целостности изложения.
[В начало ⮍](#2-3-5-6-создание-вложенного-класса) [Наверх ⮍](#2-основные-типы-данных-выражения)
[^1]: Впрочем, использование нелатинских букв является дурным тоном. *Прим. науч. ред.* [^1]: Впрочем, использование нелатинских букв является дурным тоном. *Прим. науч. ред.*
[^2]: С99 обновленная спецификация C, в том числе добавляющая поддержку знаков Юникода. *Прим. пер.* [^2]: С99 обновленная спецификация C, в том числе добавляющая поддержку знаков Юникода. *Прим. пер.*
[^3]: Сам язык не поддерживает восьмеричные литералы, но поскольку они присутствуют в некоторых C-подобных языках, в стандартную библиотеку был добавлен соответствующий шаблон. Теперь запись `std.conv.octal!777` аналогична записи `0777` в C. *Прим. науч. ред.* [^3]: Сам язык не поддерживает восьмеричные литералы, но поскольку они присутствуют в некоторых C-подобных языках, в стандартную библиотеку был добавлен соответствующий шаблон. Теперь запись `std.conv.octal!777` аналогична записи `0777` в C. *Прим. науч. ред.*