Browse Source

Глава 2 закончена

Alexander 2 years ago
parent
commit
09dc3df444
18 changed files with 261 additions and 1 deletions
  1. 35 1
      02-основные-типы-данных-выражения/README.md
  2. 20 0
      02-основные-типы-данных-выражения/src/chapter-2-2-5-1/app.d
  3. 19 0
      02-основные-типы-данных-выражения/src/chapter-2-2-5-2/app.d
  4. 8 0
      02-основные-типы-данных-выражения/src/chapter-2-2-5/app.d
  5. 21 0
      02-основные-типы-данных-выражения/src/chapter-2-2-6/app.d
  6. 20 0
      02-основные-типы-данных-выражения/src/chapter-2-2-7/app.d
  7. 15 0
      02-основные-типы-данных-выражения/src/chapter-2-3-10/app.d
  8. 20 0
      02-основные-типы-данных-выражения/src/chapter-2-3-11/app.d
  9. 10 0
      02-основные-типы-данных-выражения/src/chapter-2-3-12-1/app.d
  10. 7 0
      02-основные-типы-данных-выражения/src/chapter-2-3-14/app.d
  11. 7 0
      02-основные-типы-данных-выражения/src/chapter-2-3-15/app.d
  12. 9 0
      02-основные-типы-данных-выражения/src/chapter-2-3-16/app.d
  13. 8 0
      02-основные-типы-данных-выражения/src/chapter-2-3-18/app.d
  14. 22 0
      02-основные-типы-данных-выражения/src/chapter-2-3-4-3/app.d
  15. 10 0
      02-основные-типы-данных-выражения/src/chapter-2-3-5-5/app.d
  16. 16 0
      02-основные-типы-данных-выражения/src/chapter-2-3-6-1/app.d
  17. 7 0
      02-основные-типы-данных-выражения/src/chapter-2-3-7/app.d
  18. 7 0
      02-основные-типы-данных-выражения/src/chapter-2-3-8/app.d

+ 35 - 1
02-основные-типы-данных-выражения/README.md

@@ -253,6 +253,8 @@ auto a = "В этой строке есть \"двойные кавычки\", 
 
 Текст умышленно перенесен на новую строку после слова `также`: строковый литерал может содержать знак перевода строки (реальное начало новой строки в исходном коде, а не комбинацию `\n`), который будет сохранен именно в этом качестве.
 
+[Исходный код](src/chapter-2-2-5/)
+
 [В начало ⮍](#2-2-5-строковые-литералы) [Наверх ⮍](#2-основные-типы-данных-выражения)
 
 #### 2.2.5.1. Строковые литералы: WYSIWYG, с разделителями, строки токенов, шестнадцатеричные и импортированные
@@ -321,6 +323,8 @@ auto x = import("resource.bin");
 
 Строка, возвращаемая функцией `import`, не проверяется на соответствие кодировке UTF-8. Это сделано намеренно – для реализации возможности включать двоичные данные.
 
+[Исходный код](src/chapter-2-2-5-1/)
+
 [В начало ⮍](#2-2-5-1-строковые-литералы-wysiwyg-с-разделителями-строки-токенов-шестнадцатеричные-и-импортированные) [Наверх ⮍](#2-основные-типы-данных-выражения)
 
 #### 2.2.5.2. Тип строкового литерала
@@ -404,6 +408,8 @@ dstring y = "Здравствуй, еще более широкий мир!"; //
 
 Если вы хотите явно указать тип строки, то можете снабдить строковый литерал суффиксом: `c`, `w` или `d`, которые заставляют тип строкового литерала принять значение `string`, `wstring` или `dstring` соответственно.
 
+[Исходный код](src/chapter-2-2-5-2/)
+
 [В начало ⮍](#2-2-5-2-тип-строкового-литерала) [Наверх ⮍](#2-основные-типы-данных-выражения)
 
 ### 2.2.6. Литералы массивов и ассоциативных массивов
@@ -438,6 +444,8 @@ auto famousNamedConstants = [ "пи" : 3.14, "e" : 2.71, "константа д
 
 Каждая ячейка литерала ассоциативного массива имеет вид `ключ: значение`. Тип ключей литерала ассоциативного массива вычисляется по массиву, в который неявно записываются все эти ключи, с помощью описанного выше способа. Тип значений вычисляется аналогично. После вычисления типа ключей `K` и типа значений `V` литерал типизируется как `V[K]`. Например, константа `famousNamedConstants` принимает тип `double[string]`.
 
+[Исходный код](src/chapter-2-2-6/)
+
 [В начало ⮍](#2-2-6-литералы-массивов-и-ассоциативных-массивов) [Наверх ⮍](#2-основные-типы-данных-выражения)
 
 ### 2.2.7. Функциональные литералы
@@ -480,6 +488,8 @@ assert(b == 1.5);
 
 Теперь тип `f` – `delegate double(int x)`. Все правила распознавания типа для `function` применимы без изменений к `delegate`. Отсюда справедливый вопрос: если конструкции `delegate` могут делать все, на что способны `function`-конструкции (в конце концов конструкции `delegate` *могут*, но *не обязаны* использовать переменные своего окружения), зачем же сначала возиться с функциями? Нельзя ли всегда использовать конструкции `delegate`? Ответ прост: все дело в эффективности. Очевидно, что конструкции `delegate` обладают доступом к большему количеству информации, а по непреложному закону природы за такой доступ приходится расплачиваться. На самом деле, размер `function` равен размеру указателя, а `delegate` – в два раза больше (один указатель на функцию, один – на окружение).
 
+[Исходный код](src/chapter-2-2-7/)
+
 [В начало ⮍](#2-2-7-функциональные-литералы) [Наверх ⮍](#2-основные-типы-данных-выражения)
 
 ## 2.3. Операции
@@ -711,6 +721,8 @@ bool
 |`shared`|`Тип`|
 |`return`|Тип, возвращаемый функцией, оператором `delegate` или указателем на функцию|
 
+[Исходный код](src/chapter-2-3-4-3/)
+
 [В начало ⮍](#2-3-4-3-выражения-is) [Наверх ⮍](#2-основные-типы-данных-выражения)
 
 #### 2.3.4.4. Выражения в круглых скобках
@@ -759,6 +771,8 @@ 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) все проверки границ при получении срезов могут быть отключены.
 
+[Исходный код](src/chapter-2-3-5-5/)
+
 [В начало ⮍](#2-3-5-5-срезы-массивов) [Наверх ⮍](#2-основные-типы-данных-выражения)
 
 #### 2.3.5.6. Создание вложенного класса
@@ -820,6 +834,8 @@ foreach (ref row; matrix)
 
 Необязательный `адрес`, расположенный сразу после ключевого слова `new`, вводит конструкцию, называемую *новым размещением*. По смыслу вариант `new(адрес) T` отличается от других: вместо выделения памяти под новый объект происходит размещение объекта по заданному `адресу`. Такие низкоуровневые средства в обычном коде не применяются. Вы можете использовать их, например, чтобы распределять память из кучи C с помощью `malloc` и затем использовать ее для хранения значений языка D.
 
+[Исходный код](src/chapter-2-3-6-1/)
+
 [В начало ⮍](#2-3-6-1-выражение-new) [Наверх ⮍](#2-основные-типы-данных-выражения)
 
 #### 2.3.6.2. Получение адреса и разыменование
@@ -882,6 +898,8 @@ foreach (ref row; matrix)
 
 Результат возведения нуля в нулевую степень – единица, а в любую другую – ноль.
 
+[Исходный код](src/chapter-2-3-7/)
+
 [В начало ⮍](#2-3-7-возведение-в-степень) [Наверх ⮍](#2-основные-типы-данных-выражения)
 
 ### 2.3.8. Мультипликативные операции
@@ -898,6 +916,8 @@ foreach (ref row; matrix)
 
 Если такое число найти невозможно, результатом `a % b` будет особое значение NaN.
 
+[Исходный код](src/chapter-2-3-8/)
+
 [В начало ⮍](#2-3-8-мультипликативные-операции) [Наверх ⮍](#2-основные-типы-данных-выражения)
 
 ### 2.3.9. Аддитивные операции
@@ -950,6 +970,8 @@ auto d = a >> b; // Результат зависит от реализации
 
 Раньше было популярно с помощью операции сдвига реализовывать быстрое целочисленное умножение на 2 (`a << 1`) или деление на 2 (`a >> 1`) – или в общем случае умножение и деление на различные степени 2. Эта техника вышла из употребления, подобно видеокассетам. Пишите просто: `a * k` или `a / k`; если значение `k` известно на этапе компиляции, компилятор гарантированно сгенерирует для вас оптимальный код с операциями сдвига и всем, что еще нужно, избавив вас от волнений по поводу тонкостей работы со знаком. Не ищите сдвига на свою голову.
 
+[Исходный код](src/chapter-2-3-10/)
+
 [В начало ⮍](#2-3-10-сдвиг) [Наверх ⮍](#2-основные-типы-данных-выражения)
 
 ### 2.3.11. Выражения in
@@ -989,6 +1011,8 @@ else
 }
 ```
 
+[Исходный код](src/chapter-2-3-11/)
+
 [В начало ⮍](#2-3-11-выражения-in) [Наверх ⮍](#2-основные-типы-данных-выражения)
 
 ### 2.3.12. Сравнение
@@ -1029,6 +1053,8 @@ void main()
 
 Вместо выражения проверки на неравенство `!(a is b)` можно использовать его краткий вариант `a !is b`.
 
+[Исходный код](src/chapter-2-3-12-1/)
+
 [В начало ⮍](#2-3-12-1-проверка-на-равенство) [Наверх ⮍](#2-основные-типы-данных-выражения)
 
 #### 2.3.12.2. Сравнение для упорядочивания
@@ -1072,6 +1098,8 @@ string line;
 line == "#\n" && writeln("Успешно принята строка #. ");
 ```
 
+[Исходный код](src/chapter-2-3-14/)
+
 [В начало ⮍](#2-3-14-логическое-и) [Наверх ⮍](#2-основные-типы-данных-выражения)
 
 ### 2.3.15. Логическое ИЛИ
@@ -1089,6 +1117,8 @@ string line;
 line.length > 0 || line = "\n";
 ```
 
+[Исходный код](src/chapter-2-3-15/)
+
 [В начало ⮍](#2-3-15-логическое-или) [Наверх ⮍](#2-основные-типы-данных-выражения)
 
 ### 2.3.16. Тернарная условная операция
@@ -1114,6 +1144,8 @@ assert(x == 10);
 
 Многие концептуальные примеры обобщенного программирования используют тернарную операцию сравнения для нахождения общего типа двух значений.
 
+[Исходный код](src/chapter-2-3-16/)
+
 [В начало ⮍](#2-3-16-тернарная-условная-операция) [Наверх ⮍](#2-основные-типы-данных-выражения)
 
 ### 2.3.17. Присваивание
@@ -1138,6 +1170,8 @@ int c = (a = b, b = 7, 8);
 
 После выполнения этого фрагмента кода переменные `a`, `b` и `c` примут значения `10`, `7` и `8` соответственно.
 
+[Исходный код](src/chapter-2-3-18/)
+
 [В начало ⮍](#2-3-18-выражения-с-запятой) [Наверх ⮍](#2-основные-типы-данных-выражения)
 
 ## 2.4. Итоги и справочник
@@ -1170,7 +1204,7 @@ int c = (a = b, b = 7, 8);
 |`a.b`|Доступ к вложенным элементам ([см. раздел 2.3.5.1](#2-3-5-1-доступ-ко-внутренним-элементам))|
 |`a++`|Постфиксный вариа нт операции увеличения на единицу ([см. раздел 2.3.5.2](#2-3-5-2-увеличение-и-уменьшение-на-единицу))|
 |`a--`|Постфиксный вариант операции уменьшения на единицу ([см. раздел 2.3.5.2](#2-3-5-2-увеличение-и-уменьшение-на-единицу))|
-|`a(<арг>)`|Оператор вызова функции (`<арг> = ` необязательный список аргументов, разделенных запятыми) ([см. раздел 2.3.5.3](#2-3-5-3-вызов-функции))|
+|`a(<арг>опционально)`|Оператор вызова функции (`<арг>опционально = ` необязательный список аргументов, разделенных запятыми) ([см. раздел 2.3.5.3](#2-3-5-3-вызов-функции))|
 |`a[<арг>]`|Оператор индексации (`<арг> = ` список аргументов, разделенных запятыми) ([см. раздел 2.3.5.4](#2-3-5-4-индексация))|
 |`a[]`|Срез в размере всего массива ([см. раздел 2.3.5.5](#2-3-5-5-срезы-массивов))|
 |`a[b .. c]`|Срез ([см. раздел 2.3.5.5](#2-3-5-5-срезы-массивов))|

+ 20 - 0
02-основные-типы-данных-выражения/src/chapter-2-2-5-1/app.d

@@ -0,0 +1,20 @@
+import std.stdio;
+
+void main()
+{
+    auto a = r"Строка с \ и " ~ `"` ~ " внутри.";
+    auto b = r"c:\games\Sudoku.exe";
+    auto c = r"ab\n";
+
+    auto d = q"[Какая-то строка с "кавычками", `обратными апострофами` и [квадратными скобками]]";
+    auto e = q"/Просто строка/";
+auto f = q"EOS
+This
+is a multi-line
+heredoc string
+EOS";
+
+    auto g = q{ foo(q{hello}); };
+    // auto h = q{ № };
+    // auto i = q{ __EOF__ };
+}

+ 19 - 0
02-основные-типы-данных-выражения/src/chapter-2-2-5-2/app.d

@@ -0,0 +1,19 @@
+import std.stdio;
+
+void main()
+{
+    writeln(typeid(typeof("Hello, world!")));           // immutable(char)[]
+
+    immutable(char)[] str = "One";
+    str = "Two";
+    writeln(typeid(typeof(str)));                       // immutable(char)[]
+
+    immutable(char)[3] a = "Hi!";
+    immutable(char)[] b = a;
+    writeln(a.length, " ", b.length);                   // 3 3
+
+    wstring x = "Здрав­ст­вуй, ши­ро­кий мир!";
+    writeln(typeid(typeof(x)));                         // immutable(wchar)[]
+    dstring y = "Здрав­ст­вуй, еще бо­лее ши­ро­кий мир!";
+    writeln(typeid(typeof(y)));                         // immutable(dchar)[]
+}

+ 8 - 0
02-основные-типы-данных-выражения/src/chapter-2-2-5/app.d

@@ -0,0 +1,8 @@
+import std.stdio;
+
+void main()
+{
+    auto crlf = "\r\n";
+    auto a = "В этой стро­ке есть \"двой­ные ка­выч­ки\", а так­же
+    пе­ре­вод стро­ки, да­же два" ~ "\n";
+}

+ 21 - 0
02-основные-типы-данных-выражения/src/chapter-2-2-6/app.d

@@ -0,0 +1,21 @@
+import std.stdio;
+
+void main()
+{
+    auto somePrimes = [ 2u, 3, 5, 7, 11, 13 ];
+    writeln(somePrimes);
+    auto someDoubles = [ 1.5, 3, 4.5 ];
+    writeln(someDoubles);
+
+    auto constants = [ 2.71, 3.14, 6.023e22 ];
+    writeln(constants);
+    constants[0] = 2.21953167;
+    writeln(constants);
+    auto salutations = [ "привет", "здравствуйте", "здорово" ];
+    writeln(salutations);
+    salutations[2] = "Да здравствует Цезарь";
+    writeln(salutations);
+
+    auto famousNamedConstants = [ "пи" : 3.14, "e" : 2.71, "константа дивана" : 2.22 ];
+    writeln(famousNamedConstants);
+}

+ 20 - 0
02-основные-типы-данных-выражения/src/chapter-2-2-7/app.d

@@ -0,0 +1,20 @@
+import std.stdio;
+
+void main()
+{
+    auto f = function double(int x) { return x / 10.; };
+    auto a = f(5);
+    assert(a == 0.5);
+
+    double function(int) e = function double(int x) { return x / 10.; };
+    auto b = e(5);
+    assert(b == 0.5);
+
+    int h = 2;
+    auto g = delegate double(int x) { return h * x / 10.; };
+    auto i = g(5);
+    assert(i == 1);
+    h = 3;
+    auto j = g(5);
+    assert(j == 1.5);
+}

+ 15 - 0
02-основные-типы-данных-выражения/src/chapter-2-3-10/app.d

@@ -0,0 +1,15 @@
+import std.stdio;
+
+void main()
+{
+    int a = -1;                 // То есть 0xFFFF_FFFF
+    int b = a << 1;
+    assert(b == -2);            // 0xFFFF_FFFE
+    writeln("a = ", a, "; b = ", b, ';');
+    int c = a >> 1;
+    assert(c == -1);            // 0xFFFF_FFFF
+    writeln("a = ", a, "; c = ", c, ';');
+    int d = a >>> 1;
+    assert(d == +2147483647);   // 0x7FFF_FFFF
+    writeln("a = ", a, "; d = ", d, ';');
+}

+ 20 - 0
02-основные-типы-данных-выражения/src/chapter-2-3-11/app.d

@@ -0,0 +1,20 @@
+import std.stdio;
+
+void main()
+{
+    double[string] table = [
+        "one": 1.0,
+        "two": 2.0
+    ];
+    writeln(table);
+    auto p = "three" in table;
+    if (p)
+    {
+        ++*p;
+    }
+    else
+    {
+        table["three"] = 3.0;
+    }
+    writeln(table);
+}

+ 10 - 0
02-основные-типы-данных-выражения/src/chapter-2-3-12-1/app.d

@@ -0,0 +1,10 @@
+import std.stdio;
+
+void main()
+{
+    auto a = "ка­кая-то стро­ка";
+    auto b = a; // a и b ссы­ла­ют­ся на один и тот же мас­сив
+    a is b && writeln("Ага, это действительно одно и то же.");
+    auto c = "какая-то (другая) строка";
+    a is c || writeln("Действительно... не одно и то же.");
+}

+ 7 - 0
02-основные-типы-данных-выражения/src/chapter-2-3-14/app.d

@@ -0,0 +1,7 @@
+import std.stdio;
+
+void main()
+{
+    string line;
+    line == "#\n" && writeln("Успешно принята строка #. ");
+}

+ 7 - 0
02-основные-типы-данных-выражения/src/chapter-2-3-15/app.d

@@ -0,0 +1,7 @@
+import std.stdio;
+
+void main()
+{
+    string line;
+    line.length > 0 || line = "\n";
+}

+ 9 - 0
02-основные-типы-данных-выражения/src/chapter-2-3-16/app.d

@@ -0,0 +1,9 @@
+import std.stdio;
+
+void main()
+{
+    int x = 5, y = 5;
+    bool which = true;
+    (which ? x : y) += 5;
+    assert(x == 10);
+}

+ 8 - 0
02-основные-типы-данных-выражения/src/chapter-2-3-18/app.d

@@ -0,0 +1,8 @@
+import std.stdio;
+
+void main()
+{
+    int a = 5;
+    int b = 10;
+    int c = (a = b, b = 7, 8);
+}

+ 22 - 0
02-основные-типы-данных-выражения/src/chapter-2-3-4-3/app.d

@@ -0,0 +1,22 @@
+import std.stdio;
+
+void main()
+{
+    bool
+        a = is(int[]),   // True, int[] – до­пус­ти­мый тип
+        b = is(int[5]),  // True, int[5] – так­же до­пус­ти­мый тип
+        c = is(int[-3]), // False, раз­мер мас­си­ва за­дан не­вер­но
+        d = is(Blah);    // False (ес­ли тип с име­нем Blah не был оп­ре­де­лен)
+
+    writeln("a = ", a, "; b = ", b, "; c = ", c, "; d = ", d, ';');
+
+    alias uint UInt;
+    assert(is(uint == UInt));
+
+    a = is(int[5] : int[]),  // true, int[5] мо­жет быть пре­об­ра­зо­ван к int[]
+    b = is(int[5] == int[]), // false; это раз­ные ти­пы
+    c = is(uint : long),     // true
+    d = is(ulong : long);    // true
+
+    writeln("a = ", a, "; b = ", b, "; c = ", c, "; d = ", d, ';');
+}

+ 10 - 0
02-основные-типы-данных-выражения/src/chapter-2-3-5-5/app.d

@@ -0,0 +1,10 @@
+import std.stdio;
+
+void main()
+{
+    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 был из­ме­нен
+}

+ 16 - 0
02-основные-типы-данных-выражения/src/chapter-2-3-6-1/app.d

@@ -0,0 +1,16 @@
+import std.stdio;
+
+void main()
+{
+    auto arr1 = new int[4];
+    assert(arr1.length == 4);
+    assert(arr1 == [ 0, 0, 0, 0 ]); // Ини­циа­ли­зи­ро­ван по умол­ча­нию
+
+    auto arr2 = new int[](4);
+    assert(arr2.length == 4);
+    assert(arr2 == [ 0, 0, 0, 0 ]); // Ини­циа­ли­зи­ро­ван по умол­ча­нию
+
+    auto matrix = new int[][](4, 8);
+    assert(matrix.length == 4);
+    assert(matrix[0].length == 8);
+}

+ 7 - 0
02-основные-типы-данных-выражения/src/chapter-2-3-7/app.d

@@ -0,0 +1,7 @@
+import std.stdio;
+
+void main()
+{
+    auto a = 2 ^^ 3;
+    writeln(a); // 8
+}

+ 7 - 0
02-основные-типы-данных-выражения/src/chapter-2-3-8/app.d

@@ -0,0 +1,7 @@
+import std.stdio;
+
+void main()
+{
+    auto a = 2 ^^ 3;
+    writeln(a); // 8
+}