diff options
| -rw-r--r-- | ru-ru/d-ru.html.markdown | 138 | 
1 files changed, 78 insertions, 60 deletions
diff --git a/ru-ru/d-ru.html.markdown b/ru-ru/d-ru.html.markdown index ecd6c44c..0a8726c9 100644 --- a/ru-ru/d-ru.html.markdown +++ b/ru-ru/d-ru.html.markdown @@ -1,16 +1,17 @@ ---- +/*---  language: d  filename: learnd-ru.d  contributors:      - ["Anton Pastukhov", "http://dprogramming.ru/"]      - ["Robert Brights-Gray", "http://lhs-blog.info/"] +    - ["Andre Polykanine", "http://oire.me/"]  lang: ru-ru  ---  D - современный компилируемый язык общего назначения с Си-подобным синтаксисом,  который сочетает удобство, продуманный дизайн и высокую производительность.  D - это С++, сделанный правильно. -```d +```d */  // Welcome to D! Это однострочный комментарий  /* многострочный @@ -53,7 +54,7 @@ void main()  int a; // объявление переменной типа int (32 бита)  float b = 12.34; // тип с плавающей точкой -double с = 56.78; // тип с плавающей точкой (64 бита) +double c = 56.78; // тип с плавающей точкой (64 бита)  /*      Численные типы в D, за исключением типов с плавающей точкой и типов @@ -63,15 +64,17 @@ double с = 56.78; // тип с плавающей точкой (64 бита)  uint d = 10; ulong e = 11;  bool b = true; // логический тип  char d = 'd';  // UTF-символ, 8 бит. D поддерживает UTF "из коробки" -wchar = 'é';   // символ UTF-16 +wchar e = 'é';   // символ UTF-16  dchar f;       // и даже UTF-32, если он вам зачем-то понадобится  string s = "для строк есть отдельный тип, это не просто массив char-ов из Си";  wstring ws = "поскольку у нас есть wchar, должен быть и  wstring";  dstring ds = "...и dstring, конечно"; +string кириллица = "Имена переменных должны быть в Unicode, но не обязательно на латинице."; +  typeof(a) b = 6; // typeof возвращает тип своего выражения. -                 // В результате, b имеет такой же тип как и a +                 // В результате, b имеет такой же тип, как и a  // Тип переменной, помеченной ключевым словом auto,  // присваивается компилятором исходя из значения этой переменной @@ -84,11 +87,11 @@ int[] arr2 = [1, 2, 3, 4]; // динамический массив  int[string] aa = ["key1": 5, "key2": 6]; // ассоциативный массив  /* -   Cтроки и массивы в D — встроенные типы. Для их использования не нужно +   Строки и массивы в D — встроенные типы. Для их использования не нужно     подключать ни внешние, ни даже стандартную библиотеку, хотя в последней     есть множество дополнительных инструментов для работы с ними.   */ -immutalbe int ia = 10;  // неизменяемый тип, +immutable int ia = 10;  // неизменяемый тип,                          // обозначается ключевым словом immutable  ia += 1;                // — вызовет ошибку на этапе компиляции @@ -100,7 +103,7 @@ enum myConsts = { Const1, Const2, Const3 };  writeln("Имя типа               : ", int.stringof); // int  writeln("Размер в байтах        : ", int.sizeof);   // 4  writeln("Минимальное значение   : ", int.min);      // -2147483648 -writeln("Максимальное значениеe : ", int.max);      // 2147483647 +writeln("Максимальное значение : ", int.max);      // 2147483647  writeln("Начальное значение     : ", int.init);     // 0. Это значение,                                                      // присвоенное по умолчанию @@ -111,17 +114,13 @@ writeln("Начальное значение     : ", int.init);     // 0. Эт  /*** Приведение типов ***/ -// Простейший вариант -int i; -double j = double(i) / 2; -  // to!(имя типа)(выражение) - для большинства конверсий  import std.conv : to; // функция "to" - часть стандартной библиотеки, а не языка  double d = -1.75;  short s = to!short(d); // s = -1  /* -   cast - если вы знаете, что делаете. Кроме того, это единственный способ  +   cast - если вы знаете, что делаете. Кроме того, это единственный способ     преобразования типов-указателей в "обычные" и наоборот  */  void* v; @@ -129,7 +128,7 @@ int* p = cast(int*)v;  // Для собственного удобства можно создавать псевдонимы  // для различных встроенных объектов -alias int newInt; // теперь можно обращаться к int так, как будто бы это newInt +alias int newInt; // теперь можно обращаться к newInt так, как будто бы это int  newInt a = 5;  alias newInt = int; // так тоже допустимо @@ -203,6 +202,25 @@ switch (a) {          break;  } +// в D есть констукция "final switch". Она не может содержать секцию "defaul" +// и применяется, когда все перечисляемые в switch варианты должны быть +// обработаны явным образом + +int dieValue = 1; +final switch (dieValue) { +    case 1: +        writeln("You won"); +        break; + +    case 2, 3, 4, 5: +        writeln("It's a draw"); +        break; + +    case 6: +        writeln("I won"); +        break; +} +  // while  while (a > 10) {      // .. @@ -245,31 +263,33 @@ foreach (c; "hello") {  foreach (number; 10..15) {      writeln(number); // численные интервалы можно указывать явным образом +                     // этот цикл выведет значения с 10 по 15, но не 15, +                     // поскольку диапазон не включает в себя верхнюю границу  }  // foreach_reverse - в обратную сторону -auto container = [ 1, 2, 3 ]; +auto container = [1, 2, 3];  foreach_reverse (element; container) {      writefln("%s ", element); // 3, 2, 1  }  // foreach в массивах и им подобных структурах не меняет сами структуры -int[] a = [1,2,3,4,5]; +int[] a = [1, 2 ,3 ,4 ,5];  foreach (elem; array) {      elem *= 2; // сам массив останется неизменным  } -writeln(a); // вывод: [1,2,3,4,5] Т.е изменений нет +writeln(a); // вывод: [1, 2, 3, 4, 5] Т.е изменений нет  // добавление ref приведет к тому, что массив будет изменяться  foreach (ref elem; array) { -    elem *= 2; // сам массив останется неизменным +    elem *= 2;  } -writeln(a); // [2,4,6,8,10] +writeln(a); // [2, 4, 6, 8, 10] -// foreach умеет расчитывать индексы элементов -int[] a = [1,2,3,4,5]; +// foreach умеет рассчитывать индексы элементов +int[] a = [1, 2, 3, 4, 5];  foreach (ind, elem; array) {      writeln(ind, " ", elem); // через ind - доступен индекс элемента,                               // а через elem - сам элемент @@ -288,7 +308,7 @@ int test(int argument) {  } -// В D используется унифицированныйй синтаксис вызова функций +// В D используется единый синтаксис вызова функций  // (UFCS, Uniform Function Call Syntax), поэтому так тоже можно:  int var = 42.test(); @@ -299,11 +319,11 @@ int var2 = 42.test;  int var3 = 42.test.test;  /* -    Аргументы в функцию передаются по значению (т. е.  функция работает не с +    Аргументы в функцию передаются по значению (т.е. функция работает не с      оригинальными значениями, переданными ей, а с их локальными копиями.      Исключение составляют объекты классов, которые передаются по ссылке.      Кроме того, любой параметр можно передать в функцию по ссылке с помощью -    ключевого слова ref +    ключевого слова "ref"  */  int var = 10; @@ -318,7 +338,7 @@ void fn2(ref int arg) {  fn1(var); // var все еще = 10  fn2(var); // теперь var = 11 -// Возвращаемое значение тоже может быть auto,  +// Возвращаемое значение тоже может быть auto,  // если его можно "угадать" из контекста  auto add(int x, int y) {      return x + y; @@ -373,13 +393,13 @@ printFloat(a); // использование таких функций - сам  // без посредства глобальных переменных или массивов  uint remMod(uint a, uint b, out uint modulus)  { -    uint remainder = a / b;  +    uint remainder = a / b;      modulus = a % b;      return remainder;  }  uint modulus;                   // пока в этой переменной ноль -uint rem = remMod(5,2,modulus); // наша "хитрая" функция, и теперь, +uint rem = remMod(5, 2, modulus); // наша "хитрая" функция, и теперь                                  // в modulus - остаток от деления  writeln(rem, " ", modulus);     // вывод: 2 1 @@ -400,9 +420,9 @@ struct MyStruct {  MyStruct str1; // Объявление переменной с типом MyStruct  str1.a = 10;   // Обращение к полю  str1.b = 20; -auto result = str1.multiply();   -MyStruct str2 = {4, 8}          // Объявление + инициальзация  в стиле Си -auto str3 = MyStruct(5, 10);    // Объявление + инициальзация  в стиле D +auto result = str1.multiply(); +MyStruct str2 = {4, 8}          // Объявление + инициализация  в стиле Си +auto str3 = MyStruct(5, 10);    // Объявление + инициализация  в стиле D  // области видимости полей и методов - 3 способа задания @@ -420,7 +440,7 @@ struct MyStruct2 {      }      /*          в дополнение к знакомым public, private и protected, в D есть еще -        область видимости "package". Поля и методы с этим атрибутам будут +        область видимости "package". Поля и методы с этим атрибутом будут          доступны изо всех модулей, включенных в "пакет" (package), но не          за его пределами. package - это "папка", в которой может храниться          несколько модулей. Например, в "import.std.stdio", "std" - это @@ -428,8 +448,8 @@ struct MyStruct2 {      */      package:          string d; -         -    /* помимо этого, имеется еще один модификатор - export, который позволяет  + +    /* помимо этого, имеется еще один модификатор - export, который позволяет      использовать объявленный с ним идентификатор даже вне самой программы !      */      export: @@ -442,10 +462,10 @@ struct MyStruct3 {               // в этом случае пустой конструктор добавляется компилятором          writeln("Hello, world!");      } -     -     -    // а вот это конструкция, одна из интересных идиом и представлет собой  -    // конструктор копирования, т.е конструктор возвращающий копию структуры. + + +    // а вот это конструкция - одна из интересных идиом и представляет собой +    // конструктор копирования, т.е конструктор, возвращающий копию структуры.      // Работает только в структурах.      this(this)      { @@ -488,7 +508,7 @@ class Outer      {          int foo()          { -            return m; // можно обращаться к полям "родительского" класса +            return m; // можно обращаться к полям "внешнего" класса          }      }  } @@ -497,10 +517,10 @@ class Outer  class Base {      int a = 1;      float b = 2.34; -     -     -    // это статический метод, т.е метод который можно вызывать обращаясь -    // классу напрямую, а не через создание экземпляра объекта + + +    // это статический метод, т.е метод который можно вызывать, обращаясь +    // к классу напрямую, а не через создание экземпляра объекта      static void multiply(int x, int y)      {          writeln(x * y); @@ -511,13 +531,13 @@ Base.multiply(2, 5); // используем статический метод.  class Derived : Base {      string c = "Поле класса - наследника"; -     -     + +      // override означает то, что наследник предоставит свою реализацию метода,      // переопределив метод базового класса      override static void multiply(int x, int y)      { -        super.multiply(x, y);  // super - это ссылка на класс-предок или базовый класс +        super.multiply(x, y);  // super - это ссылка на класс-предок, или базовый класс          writeln(x * y * 2);      }  } @@ -538,7 +558,7 @@ class Derived : FC { // это вызовет ошибку      float b;  } -// Абстрактный класс не можен быть истанциирован, но может иметь наследников +// Абстрактный класс не может быть истанциирован, но может иметь наследников  abstract class AC {      int a;  } @@ -547,8 +567,8 @@ auto ac = new AC(); // это вызовет ошибку  class Implementation : AC {      float b; -     -     // final перед методом нефинального класса означает запрет возможности  + +     // final перед методом нефинального класса означает запрет возможности       // переопределения метода      final void test()      { @@ -560,7 +580,7 @@ auto impl = new Implementation(); // ОК -/*** Микшины (mixins) ***/ +/*** Примеси (mixins) ***/  // В D можно вставлять код как строку, если эта строка известна на этапе  // компиляции. Например: @@ -583,8 +603,8 @@ void main() {  /*** Шаблоны ***/  /* -    Шаблон функции. Эта функция принимает аргументы разеых типов, которые -    подсталяются вместо T на этапе компиляции. "T" - это не специальный +    Шаблон функции. Эта функция принимает аргументы разных типов, которые +    подставляются вместо T на этапе компиляции. "T" - это не специальный      символ, а просто буква. Вместо "T" может быть любое слово, кроме ключевого.   */  void print(T)(T value) { @@ -633,8 +653,8 @@ class Stack(T)  void main() {      /* -        восклицательный знак - признак шаблона В данном случае мы создаем  -        класс и указывем, что "шаблонное" поле будет иметь тип string +        восклицательный знак - признак шаблона. В данном случае мы создаем +        класс и указываем, что "шаблонное" поле будет иметь тип string      */     auto stack = new Stack!string; @@ -660,9 +680,7 @@ void main() {     несколько единообразных функций, определяющих, _как_ мы получаем доступ     к элементам контейнера, вместо того, чтобы описывать внутреннее устройство     этого контейнера. Сложно? На самом деле не очень. -*/ -/*      Простейший вид диапазона - Input Range. Для того, чтобы превратить любой      контейнер в Input Range, достаточно реализовать для него 3 метода:      - empty - проверяет, пуст ли контейнер @@ -706,8 +724,8 @@ struct StudentRange  void main(){      auto school = School([ -            Student("Mike", 1),  -            Student("John", 2) ,  +            Student("Mike", 1), +            Student("John", 2) ,              Student("Dan", 3)      ]);      auto range = StudentRange(school); @@ -730,6 +748,6 @@ void main(){  ```  ## Что дальше? -[Официальный сайт](http://dlang.org/) -[Онлайн-книга](http://ddili.org/ders/d.en/) -[Официальная вики](http://wiki.dlang.org/) +- [Официальный сайт](http://dlang.org/) +- [Онлайн-книга](http://ddili.org/ders/d.en/) +- [Официальная вики](http://wiki.dlang.org/)  | 
