diff options
Diffstat (limited to 'ru-ru')
| -rw-r--r-- | ru-ru/.directory | 4 | ||||
| -rw-r--r-- | ru-ru/bash-ru.html.markdown | 9 | ||||
| -rw-r--r-- | ru-ru/bf.html.markdown (renamed from ru-ru/brainfuck-ru.html.markdown) | 2 | ||||
| -rw-r--r-- | ru-ru/c++-ru.html.markdown | 892 | ||||
| -rw-r--r-- | ru-ru/d-ru.html.markdown | 754 | ||||
| -rw-r--r-- | ru-ru/erlang-ru.html.markdown | 2 | ||||
| -rw-r--r-- | ru-ru/java-ru.html.markdown | 46 | ||||
| -rw-r--r-- | ru-ru/markdown-ru.html.markdown | 300 | ||||
| -rw-r--r-- | ru-ru/objective-c-ru.html.markdown | 27 | ||||
| -rw-r--r-- | ru-ru/perl-ru.html.markdown | 195 | ||||
| -rw-r--r-- | ru-ru/php-ru.html.markdown | 57 | ||||
| -rw-r--r-- | ru-ru/python3-ru.html.markdown | 2 | ||||
| -rw-r--r-- | ru-ru/tmux-ru.html.markdown | 252 | ||||
| -rw-r--r-- | ru-ru/typescript-ru.html.markdown | 173 | 
14 files changed, 2551 insertions, 164 deletions
| diff --git a/ru-ru/.directory b/ru-ru/.directory new file mode 100644 index 00000000..4d20336b --- /dev/null +++ b/ru-ru/.directory @@ -0,0 +1,4 @@ +[Dolphin] +SortRole=size +Timestamp=2015,10,31,18,6,13 +Version=3 diff --git a/ru-ru/bash-ru.html.markdown b/ru-ru/bash-ru.html.markdown index 21377b6c..5e99afc2 100644 --- a/ru-ru/bash-ru.html.markdown +++ b/ru-ru/bash-ru.html.markdown @@ -95,6 +95,15 @@ else      echo "Имя совпадает с именем пользователя"  fi +# Примечание: если $Name пустой, bash интерпретирует код как: +if [ -ne $USER ] +# а это ошибочная команда +# поэтому такие переменные нужно использовать так: +if [ "$Name" -ne $USER ] ... +# когда $Name пустой, bash видит код как: +if [ "" -ne $USER ] ... +# что работает правильно +  # Также есть условное исполнение  echo "Исполнится всегда" || echo "Исполнится, если первая команда завершится ошибкой"  echo "Исполнится всегда" && echo "Исполнится, если первая команда выполнится удачно" diff --git a/ru-ru/brainfuck-ru.html.markdown b/ru-ru/bf.html.markdown index fcee185f..20f0fa56 100644 --- a/ru-ru/brainfuck-ru.html.markdown +++ b/ru-ru/bf.html.markdown @@ -1,5 +1,5 @@  --- -language: brainfuck +language: bf  contributors:      - ["Prajit Ramachandran", "http://prajitr.github.io/"]      - ["Mathias Bynens", "http://mathiasbynens.be/"] diff --git a/ru-ru/c++-ru.html.markdown b/ru-ru/c++-ru.html.markdown new file mode 100644 index 00000000..0cf580d5 --- /dev/null +++ b/ru-ru/c++-ru.html.markdown @@ -0,0 +1,892 @@ +--- +language: c++ +filename: learncpp-ru.cpp +contributors: +    - ["Steven Basart", "http://github.com/xksteven"] +    - ["Matt Kline", "https://github.com/mrkline"] +    - ["Geoff Liu", "http://geoffliu.me"] +    - ["Connor Waters", "http://github.com/connorwaters"] +translators: +    - ["Bohdan Shtepan", "http://modern-dev.com"] +lang: ru-ru +--- + +C++ - компилируемый, статически типизированный язык программирования общего назначения, который, +[как заявляет создатель языка Бьёрн Страуструп](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote), +был разработан как + +- "лучшая замена C" +- язык с поддержкой абстракции данных +- язык с поддержкой объектно-ориентированого программирования +- язык с поддержкой обобщенного программирования + +Хотя его синтаксис может показаться более трудным или сложным для понимания, чем в более современных языках, +он широко применяется, так как код, написанный на C++, компилируется в набор инструкций, которые могут быть выполнены напрямую +процессором. C++ широко используется для разработки программного обеспечения, являясь одним из самых популярных языков +программирования. Область его применения включает создание операционных систем, разнообразных прикладных программ, драйверов +устройств, приложений для встраиваемых систем, высокопроизводительных серверов, а также развлекательных приложений (игр). + +```c++ +////////////////// +// Сравнение с C +////////////////// + +// C++ практически представляет собой надмножество C и имеет схожий синтаксис +// для объявления переменных, примитивов и функций. + +// Так же, как и в С, точкой входа в программу является функция с именем main, +// которая возвращает целочисленное значение. +// Это значение является кодом ответа программы. +// Смотрите https://goo.gl/JYGKyv для более подробной информации. +int main(int argc, char** argv) +{ +    // Аргументы командной строки, переданные в программу, хранятся в переменных +	// argc и argv, так же, как и в C. +    // argc указывает на количество аргументов, +    // а argv является массивом C-подобных строк (char*), который непосредсвенно +	// содержит аргументы. +    // Первым аргументом всегда передается имя программы. +    // argc и argv могут быть опущены, если вы не планируете работать с аругментами +	// коммандной строки. +	// Тогда сигнатура функции будет иметь следующий вид: int main() + +    // Возвращаемое значение 0 указывает на успешное завершение программы. +    return 0; +} + +// Тем не менее, C++ имеет свои отличия: + +// В C++ символьные литералы имеют тип char. +sizeof('c') == sizeof(char) == 1 + +// В C символьные литералы - целые числа. +sizeof('c') == sizeof(int) + + +// C++ имеет строгое прототипирование. +void func(); // функция, которая не принимает аргументов. + +// В языке C +void func(); // функция, которая может принять сколько угодно аргументов. + +// Использование nullptr вместо NULL в C++. +int* ip = nullptr; + +// Стандартные заголовочные файлы С доступны в С++, +// но с префиксом "с" и не имеют суффикса .h. +#include <cstdio> + +int main() +{ +    printf("Hello, world!\n"); +    return 0; +} + +/////////////////////// +// Перегрузка функций +/////////////////////// + +// С++ поддерживает перегрузку функций, при условии, +// что каждая функция принимает различные параметры. + +void print(char const* myString) +{ +    printf("String %s\n", myString); +} + +void print(int myInt) +{ +    printf("My int is %d", myInt); +} + +int main() +{ +    print("Hello"); // Использование void print(const char*) +    print(15); // Использование void print(int) +} + +///////////////////////////// +// Аргументы функций по умолчанию +///////////////////////////// + +// Вы можете предоставить аргументы по умолчанию для функции, +// если они не предоставлены при вызове функции. + +void doSomethingWithInts(int a = 1, int b = 4) +{ +    // Здесь что-то делаем с числами +} + +int main() +{ +    doSomethingWithInts();      // a = 1,  b = 4 +    doSomethingWithInts(20);    // a = 20, b = 4 +    doSomethingWithInts(20, 5); // a = 20, b = 5 +} + +// Аргументы по умолчанию должны быть в конце списка аргументов. + +void invalidDeclaration(int a = 1, int b) // Ошибка! +{ +} + + +///////////// +// Пространства имен +///////////// + +// Пространства имен предоставляют отдельные области для переменной, +// функции и других объявлений. +// Пространства имен могут быть вложенными. + +namespace First { +    namespace Nested { +        void foo() +        { +            printf("This is First::Nested::foo\n"); +        } +    } // конец пространства имен Nested +} // конец пространства имен First + +namespace Second { +    void foo() +    { +        printf("This is Second::foo\n") +    } +} + +void foo() +{ +    printf("This is global foo\n"); +} + +int main() +{ +    // Включает все функци из пространства имен Second в текущую область видимости. +    // Обратите внимание, что простой вызов foo() больше не работает, +    // так как теперь не ясно, вызываем ли мы foo из пространства имен Second, или +	// из глобальной области видимости. +    using namespace Second; + +    Second::foo(); // напечатает "This is Second::foo" +    First::Nested::foo(); // напечатает "This is First::Nested::foo" +    ::foo(); // напечатает "This is global foo" +} + +/////////////// +// Ввод и вывод +/////////////// + +// Ввод и вывод в C++ использует потоки +// cin, cout и cerr представляют потоки stdin, stdout и stderr. +// << - оператор вставки, >> - оператор извлечения. + +#include <iostream> // Включение файла для работы с потоками Ввода\Вывода. + +using namespace std; // Потоки доступны в пространстве имен std (стандартная библиотека) + +int main() +{ +   int myInt; + +   // Выводит в stdout (или в терминал/на экран) +   cout << "Enter your favorite number:\n"; +   // Принимает ввод +   cin >> myInt; + +   // cout может принимать форматирование +   cout << "Your favorite number is " << myInt << "\n"; +   // напечатает "Your favorite number is <myInt>" + +    cerr << "Used for error messages"; +} + +////////// +// Строки +////////// + +// Строки в C++ являются объектами и имеют много функций-членов. +#include <string> + +using namespace std; // Строки также доступны в пространстве имен std (стандартная библиотека) + +string myString = "Hello"; +string myOtherString = " World"; + +// + используется для конкатенации строк. +cout << myString + myOtherString; // "Hello World" + +cout << myString + " You"; // "Hello You" + +// Строки в C++ могут изменяться и имеют семантику значений. +myString.append(" Dog"); +cout << myString; // "Hello Dog" + + +///////////// +// Ссылки +///////////// + +// Кроме указателей, доступных в C, +// C++ имеет _ссылки_. +// Это такой тип указателя, который не может быть переназначен после инициализации +// и не может иметь значения null. +// Ссылки имеют схожий с переменными синтаксис: +// * больше не используется для разыменования и +// & (адрес) не используется для назначения. + +using namespace std; + +string foo = "I am foo"; +string bar = "I am bar"; + + +string& fooRef = foo; // Здесь создается ссылка на foo. +fooRef += ". Hi!"; // Изменяет foo по ссылке +cout << fooRef; // Печатает "I am foo. Hi!" + +// Не переназначает "fooRef". Это то же самое, что и "foo = bar", и +//   foo == "I am bar" +// после этой строчки. +cout << &fooRef << endl; // Печатает адрес foo +fooRef = bar; +cout << &fooRef << endl; // По-прежнему печатает адрес foo +cout << fooRef;  // Печатает "I am bar" + +// Адрес fooRef остается тем же, то есть он по-прежнему ссылается на foo. + + +const string& barRef = bar; // Создает константную ссылку. +// Так же, как и в C, константные значения (а также указатели и ссылки) не могут быть изменены. +barRef += ". Hi!"; // Ошибка, константная ссылка не может быть изменена. + +// Обходной путь: Прежде чем мы рассмотрим указатели более детально, нам нужно ознакомиться +// с концепцией, известной как "временный объект". Представьте, что мы имеем следующий код +string tempObjectFun() { ... } +string retVal = tempObjectFun(); + +// Вот что на самом деле происходит во второй строке: +//   - tempObjectFun возвращает строковый объект +//   - из возвращаемого объекта создается новая строка в качестве аргумента конструктору +//   - возвращаемый объект уничтожается +// Возвращаемый объект называется временным объектом. Временные объекты создаются, +// когда функция возвращает объект, и уничтожаются в конце выполнения обрамляющего +// выражения (По крайней мере, так это описывает спецификация, хотя компиляторы могут +// изменять это поведение. Для более подробной информации смотрите "оптимизация +// возвращаемого значения".) Таким образом в этом коде: +foo(bar(tempObjectFun())) + +// предполагая, что foo и bar существуют, объект, возвращаемый tempObjectFun, передается +// в bar, и уничтожается перед вызовом foo. + +// Возвращаемся к указателям. Исключением для правила "в конце выполнения обрамляющего +// выражения" является временный объект, привязанный к ссылке const, в этом случае +// его жизненный цикл продлевается до текущей области видимости: + +void constReferenceTempObjectFun() { +  // constRef получает временный объект, и он действителен до конца этой функции. +  const string& constRef = tempObjectFun(); +  ... +} + +// В C++11 предоставлен еще один тип ссылок специально для временных объектов. +// objects. Вы не можете объявить переменную этого типа, но он имеет приоритет +// в резолюции перегрузки: + +void someFun(string& s) { ... }  // Обычная ссылка +void someFun(string&& s) { ... }  // Ссылка на временный объект + +string foo; +someFun(foo);  // Выполняет версию с обычной ссылкой +someFun(tempObjectFun());  // Выполняет версию с временной ссылкой. + +// Например, существуют следующие две версии конструктора std::basic_string: +basic_string(const basic_string& other); +basic_string(basic_string&& other); + +// Идея в том, что если мы конструируем новую строку из временного объекта (который  +// так или иначе будет уничтожен), мы можем использовать более эффективный конструктор, +// который "спасает" части этой временной строки. Эта концепция была названа +// "move semantics". + +///////////////////// +// Перечисления +///////////////////// + +// Перечисления - способ объявления констант и установки их значений, в основном +// использующийся для упрощения чтения кода. +enum ECarTypes +{ +  Sedan, +  Hatchback, +  SUV, +  Wagon +}; + +ECarTypes GetPreferredCarType() +{ +	return ECarTypes::Hatchback; +} + +// На момент выхода C++11 есть простой способ назначения типа перечисления, что +// полезно в случае сериализации данных и преобразований между конечным типом и  +// соответствующими константами. +enum ECarTypes : uint8_t +{ +  Sedan, // 0 +  Hatchback, // 1 +  SUV = 254, // 254 +  Hybrid // 255 +}; + +void WriteByteToFile(uint8_t InputValue) +{ +	// Сериализуем InputValue в файл +} + +void WritePreferredCarTypeToFile(ECarTypes InputCarType) +{ +	// Перечисление неявно преобразуется в uint8_t из-за ранее объявленного +	// типа перечисления. +	WriteByteToFile(InputCarType); +} + +// С другой стороны, чтобы избежать случайного приведения к целочисленному типу или +// другому перечислению, вы можете создать класс перечисления, который не будет +// преобразовываться неявно. +enum class ECarTypes : uint8_t +{ +  Sedan, // 0 +  Hatchback, // 1 +  SUV = 254, // 254 +  Hybrid // 255 +}; + +void WriteByteToFile(uint8_t InputValue) +{ +	// Сериализуем InputValue в файл +} + +void WritePreferredCarTypeToFile(ECarTypes InputCarType) +{ +	// Хотя ECarTypes имеет тип uint8_t, код не будет скомпилирован из-за того, +	// что перечисление было объявлено как класс перечисления. +	WriteByteToFile(InputCarType); +} + +////////////////////////////////////////// +// Классы и объектно-ориентированное программирование +////////////////////////////////////////// + +// Пример классов +#include <iostream> + +// Объявление класса. +// Обычно классы объявляют в заголовочном (.h или .hpp) файле. +class Dog { +    // Переменные-члены и функции являются приватными по умолчанию. +    std::string name; +    int weight; + +// Все члены после этой сроки являются открытыми +// пока "private:" или "protected:" не будет объявлено. +public: + +    // Конструктор по умолчанию +    Dog(); + +    // Объявление функций-членов +    // Обратите внимание, мы используем std::string здесь вместо использования +    // using namespace std; +    // выше. +    // Никогда не размещайте выражение "using namespace" в заголовке. +    void setName(const std::string& dogsName); + +    void setWeight(int dogsWeight); + +    // Функции, которые не изменяют состояние объекта, +    // должны быть помечены как const. +    // Это позволяет вызывать их, если дана const ссылка на объект. +    // Обратите внимание, функции должны быть явно объявлены как _virtual_, +    // если вы хотите перегрузить их в производных классах. +    // Функции не являются виртуальными по умолчанию для повышения производительности. +    virtual void print() const; + +    // Также функции могут быть определены внутри тела класса. +    // Функции, определенные следующим образом, автоматически встроены. +    void bark() const { std::cout << name << " barks!\n"; } + +    // Наряду с конструкторами, в C++ есть деструкторы. +    // Они вызываются, когда объект удаляется или выпадает из области видимости. +    // Это активирует мощную парадигму программирования, известную как RAII +    // (смотрите ниже) +    // Деструктор должен быть виртуальным, если класс будет производным. +    // Если он не виртуальный, тогда деструктор производного класса не будет вызван, +    // если объект удален по ссылке или указателю базового класса. +    virtual ~Dog(); + +}; // Определение класса должно завершаться точкой с запятой. + +// Функции-члены класса, как правило, реализуются в .cpp файлах. +Dog::Dog() +{ +    std::cout << "A dog has been constructed\n"; +} + +// Объекты (такие как строки) должны передаваться по ссылке если вы будете +// изменять их, или const-ссылке если нет. +void Dog::setName(const std::string& dogsName) +{ +    name = dogsName; +} + +void Dog::setWeight(int dogsWeight) +{ +    weight = dogsWeight; +} + +// Обратите внимание, "virtual" требуется только в объявлении, не в определении. +void Dog::print() const +{ +    std::cout << "Dog is " << name << " and weighs " << weight << "kg\n"; +} + +Dog::~Dog() +{ +    cout << "Goodbye " << name << "\n"; +} + +int main() { +    Dog myDog; // Печатает "A dog has been constructed" +    myDog.setName("Barkley"); +    myDog.setWeight(10); +    myDog.print(); // Печатает "Dog is Barkley and weighs 10 kg" +    return 0; +} // Печатает "Goodbye Barkley" + +// Интерфейсы: + +// Этот класс наследует все открытые и защищенные члены класса Dog +// так же, как и все закрытые, но не может непосредственно получить доступ к закрытым +// членам\методам без открытых или защищенных методов для этого. +class OwnedDog : public Dog { + +    void setOwner(const std::string& dogsOwner); + +    // Переопределяем поведение функции печати для всех OwnedDog. Смотрите +    // https://goo.gl/3kuH2x для боле общего введения, если вы не знакомы +    // с концепцией полиморфизма подтипов (включения). +    // Ключевое слово override является необязательным, но указывает, что метод +    // на самом деле перегружается в базовом классе. +    void print() const override; + +private: +    std::string owner; +}; + +// Тем временем, в соответствующем .cpp файле: + +void OwnedDog::setOwner(const std::string& dogsOwner) +{ +    owner = dogsOwner; +} + +void OwnedDog::print() const +{ +    Dog::print(); // Вызывает функцию print в базовом классе Dog +    std::cout << "Dog is owned by " << owner << "\n"; +    // Печатает "Dog is <name> and weights <weight>" +    //        "Dog is owned by <owner>" +} + +////////////////////////////////////////// +// Инициализация и перегрузка операторов. +////////////////////////////////////////// + +// В C++ вы можете перегрузить поведение таких операторов: +, -, *, / и др.. +// Это делается путем определения функции, которая вызывается, +// когда используется оператор. + +#include <iostream> +using namespace std; + +class Point { +public: +    // Значения по умолчанию для переменных-членов могут быть установлены +	// следующим образом. +    double x = 0; +    double y = 0; + +    // Определяем новый конструктор, который инициализирует Point со значениями +    // по умолчанию (0, 0) +    Point() { }; + +    // Следующий синтаксис известен как список инициализации и является верным способом  +	// инициализировать значения членов класса. +    Point (double a, double b) : +        x(a), +        y(b) +    { /* Ничего не делайте, кроме инициализации значений */ } + +    // Перегружаем оператор +. +    Point operator+(const Point& rhs) const; + +    // Перегружаем оператор +=. +    Point& operator+=(const Point& rhs); + +    // Имеет смысл добавить перегрузку операторов - и -=, +    // но для краткости мы опустим эти детали. +}; + +Point Point::operator+(const Point& rhs) const +{ +    // Создает новую точку, которая является суммой этой точки и rhs. +    return Point(x + rhs.x, y + rhs.y); +} + +Point& Point::operator+=(const Point& rhs) +{ +    x += rhs.x; +    y += rhs.y; +    return *this; +} + +int main () { +    Point up (0,1); +    Point right (1,0); +    // Здесь происходит вызов оператора + класса Point +    // Точка "up" вызывает + (функция) с параметром "right" +    Point result = up + right; +    // Печатает "Result is upright (1,1)" +    cout << "Result is upright (" << result.x << ',' << result.y << ")\n"; +    return 0; +} + +///////////////////// +// Шаблоны +///////////////////// + +// Шаблоны в С++, в основном, используются для обобщенного программирования, хотя +// они гораздо более мощны, чем дженерики в других языках. Они также поддерживают +// явные, частные и функциональные типы классов; на самом деле, они являются +// тьюринг-полным языком, встроенным в C++! + +// Мы начнем с наиболее распространенного типа обобщенного программирования. Чтобы +// определить класс или функцию, которая принимает параметр типа: +template<class T> +class Box { +public: +    // В этом классе T может быть любого типа. +    void insert(const T&) { ... } +}; + +// Во время компиляции компилятор фактически генерирует копии каждого шаблона +// с замещенными параметрами, поэтому полное определение класса должно присутствовать +// при каждом вызове. Именно поэтому классы шаблонов полностью определены в +// заголовочных файлах. + +// Чтобы создать экземпляр класса шаблона на стеке: +Box<int> intBox; + +// и вы можете использовать его, как и ожидалось: +intBox.insert(123); + +// Вы, конечно, можете использовать вложенные шаблоны: +Box<Box<int> > boxOfBox; +boxOfBox.insert(intBox); + +// Вплоть до С++11, вы должны были ставить пробел между двумя символами '>', иначе '>>' +// принимался парсером, как оператор сдвига вправо. + +// Иногда вы можете увидеть +//   template<typename T> +// вместо этого. В этом случае ключевые слова 'class' и 'typename' _в основном_ +// взаимозаменяемыми. Для более подробной информации смотрите +//   http://en.wikipedia.org/wiki/Typename +// (да-да, это ключевое слово имеет собственную страничку на вики). + +// Аналогичным образом, шаблонная функция: +template<class T> +void barkThreeTimes(const T& input) +{ +    input.bark(); +    input.bark(); +    input.bark(); +} + +// Обратите внимание, что здесь ничего не указано о типе параметра. Компилятор +// будет генерировать и затем проверять на тип каждый вызов шаблона, поэтому +// данная функция работает с любым типом 'T', который имеет метод 'bark'. + +Dog fluffy; +fluffy.setName("Fluffy"); +barkThreeTimes(fluffy); // Печатает "Fluffy barks" три раза. + +//Параметры шаблона не должны быть классами: +template<int Y> +void printMessage() { +  cout << "Learn C++ in " << Y << " minutes!" << endl; +} + +// В конце концов, вы можете явно специализировать шаблоны для более эффективного +// кода. Конечно, большинство реальных случаев использования специализации +// не так тривиально, как это. Обратите внимание, вам все еще нужно явно объявить +// функцию (или класс) в качестве шаблона, даже если вы явно указали все параметры. +template<> +void printMessage<10>() { +  cout << "Learn C++ faster in only 10 minutes!" << endl; +} + +printMessage<20>();  // Печатает "Learn C++ in 20 minutes!" +printMessage<10>();  // Печатает "Learn C++ faster in only 10 minutes!" + + +///////////////////// +// Обработка исключений +///////////////////// + +// Стандартная библиотека предоставляет несколько типов исключений +// (смотрите http://en.cppreference.com/w/cpp/error/exception) +// но, в принципе, любой тип может быть брошен в качестве исключения. +#include <exception> +#include <stdexcept> + +// Все исключения, брошенные в блоке _try_ могут быть пойманы в последующем блоке +// _catch_. +try { +    // Не выделяйте память в куче для исключений с помощью ключевого слова _new_. +    throw std::runtime_error("A problem occurred"); +} + +// Поймайте исключение по константной ссылке, если оно является объектом +catch (const std::exception& ex) +{ +    std::cout << ex.what(); +} + +// Ловит любое исключение, не пойманное предыдущим блоком _catch_ +catch (...) +{ +    std::cout << "Unknown exception caught"; +    throw; // Повторный выброс исключения +} + +/////// +// Получение ресурса есть инициализация (RAII) +/////// + +// Программная идиома объектно-ориентированного программирования, смысл которой +// заключается в том, что с помощью тех или иных программных механизмов получение +// некоторого ресурса неразрывно совмещается с инициализацией, а освобождение - +// с уничтожением объекта. + +// Чтобы понять, на сколько это полезно, +// рассмотрим функцию, которая использует обработчик файлов в С: +void doSomethingWithAFile(const char* filename) +{ +    // Для начала, предположим, ничего не может потерпеть неудачу. + +    FILE* fh = fopen(filename, "r"); // Открываем файл в режиме чтения. + +    doSomethingWithTheFile(fh); +    doSomethingElseWithIt(fh); + +    fclose(fh); // Закрываем обработчик файла. +} + +// К сожалению, вещи быстро осложняются обработкой ошибок. +// Предположим, fopen может потерпеть неудачу, тогда doSomethingWithTheFile и +// doSomethingElseWithIt вернут коды ошибок, если потерпят неудачу. +//  (Исключения являются предпочтительным способом обработки ошибок, +//   но некоторые программисты, особенно те, кто имеет большой опыт работы с С, +//   не согласны с аргументами о полезности исключений). +// Теперь мы должны проверить каждый вызов на наличие ошибок и закрыть обработчик +// файла, если он есть. +bool doSomethingWithAFile(const char* filename) +{ +    FILE* fh = fopen(filename, "r"); // Открывает файл в режиме чтения +    if (fh == nullptr) // В случае неудачи возвращаемый указатель принимает значение null. +        return false; // Сообщает о неудаче вызывающему. + +    // Предположим, каждая функция возвращает false в случае неудачи +    if (!doSomethingWithTheFile(fh)) { +        fclose(fh); // Закрываем обработчик файла, чтобы не было утечек +        return false; // Сообщает об ошибке. +    } +    if (!doSomethingElseWithIt(fh)) { +        fclose(fh); // Закрываем обработчик файла, чтобы не было утечек +        return false; // Сообщает об ошибке. +    } + +    fclose(fh); // Закрываем обработчик файла, чтобы не было утечек +    return true; // Указывает на успех +} + +// C-программисты часто упорядочивают это с помощью goto: +bool doSomethingWithAFile(const char* filename) +{ +    FILE* fh = fopen(filename, "r"); +    if (fh == nullptr) +        return false; + +    if (!doSomethingWithTheFile(fh)) +        goto failure; + +    if (!doSomethingElseWithIt(fh)) +        goto failure; + +    fclose(fh); // Закрываем файл. +    return true; // Указывает на успех + +failure: +    fclose(fh); +    return false; // Сообщает об ошибке. +} + +// Если функции указывают на ошибки с помощью исключений, вещи становятся проще, +// но все еще не оптимальны. +void doSomethingWithAFile(const char* filename) +{ +    FILE* fh = fopen(filename, "r"); // Открываем файл в режиме чтения +    if (fh == nullptr) +        throw std::runtime_error("Could not open the file."); + +    try { +        doSomethingWithTheFile(fh); +        doSomethingElseWithIt(fh); +    } +    catch (...) { +        fclose(fh); // Убедитесь, что закрываете файл, если происходит ошибка. +        throw; // Затем повторно бросает исключение. +    } + +    fclose(fh); // Закрываем файл. +    // Успех +} + +// Сравните это с использованием класса потока файла (fstream) в С++, который +// использует свой деструктор, чтобы закрыть файл. Еще раз взгляните выше, +// деструктор вызывается автоматически, когда объект выпадает из области видимости. +void doSomethingWithAFile(const std::string& filename) +{ +    // ifstream определяет файловый поток +    std::ifstream fh(filename); // Открыть файл + +    // Что-то делать с файлом +    doSomethingWithTheFile(fh); +    doSomethingElseWithIt(fh); + +} // Здесь файл автоматически закрывается в деструкторе. + +// Это имеет _огромнейшие_ преимущества: +// 1. Неважно, что произойдет, +//    ресурсы (в данном случае дескриптор файла) будут очищены. +//    После того, как вы правильно напишете деструктор, +//    Больше будет _невозможно_ закрыть обработчик файлов или допустить утечку. +// 2. Обратите внимание, что код намного проще. +//    Деструктор закрывает файловый поток "за кулисами", и вам больше не нужно об +//     этом беспокоиться. +// 3. Код устойчив к исключениям. +//    Исключение может быть брошено в любом месте в функции, и это никак не повлияет +//    на очистку. + +// Весь идиоматический код на С++ широко использует RAII для всех ресурсов. +// Дополнительные примеры включат: +// - Использование памяти unique_ptr и shared_ptr +// - Контейнеры - стандартная библиотека связанных списков, векторы  +//   (т.е. самоизменяемые массивы), хэш-таблицы и все остальное автоматически +//    уничтожается сразу же, когда выходит за пределы области видимости. +// - Ипользование мьютексов lock_guard и unique_lock + +// Контейнеры с пользовательскими классами в качестве ключей требуют +// сравнивающих функций в самом объекте или как указатель на функцию. Примитивы +// имеют компараторы по умолчанию, но вы можете перегрузить их. +class Foo { +public: +	int j; +	Foo(int a) : j(a) {} +}; +struct compareFunction { +    bool operator()(const Foo& a, const Foo& b) const { +        return a.j < b.j; +    } +}; +// это не допускается (хотя это может варьироваться в зависимости от компилятора) +// std::map<Foo, int> fooMap; +std::map<Foo, int, compareFunction> fooMap; +fooMap[Foo(1)]  = 1; +fooMap.find(Foo(1)); //true + +///////////////////// +// Веселые вещи +///////////////////// + +// Аспекты С++, которые могут быть удивительными для новичков (и даже для некоторых +// ветеранов). Этот раздел, к сожалению, очень неполон. С++ является одним из самых +// простых языков, где очень легко выстрелить себе в ногу. + +// Вы можете перегрузить приватные методы! +class Foo { +  virtual void bar(); +}; +class FooSub : public Foo { +  virtual void bar();  // Перегружает Foo::bar! +}; + + +// 0 == false == NULL (в основном)! +bool* pt = new bool; +*pt = 0; // Устанавливает значение указателя 'pt' в false. +pt = 0;  // Устанавливает значение 'pt' в нулевой указатель. Обе строки проходят +		// компиляцию без ошибок. + +// nullptr приходит на помощь: +int* pt2 = new int; +*pt2 = nullptr; // Не пройдет компиляцию +pt2 = nullptr;  // Устанавливает pt2 в null. + +// Существует исключение для булевых значений. +// Это позволит вам проверить указатели с помощью if(!ptr), +// но как следствие вы можете установить nullptr в bool напрямую! +*pt = nullptr;  // Это по прежнему проходит компиляцию, даже если '*pt' - bool! + + +// '=' != '=' != '='! +// Вызывает Foo::Foo(const Foo&) или некий вариант (смотрите "move semantics") +// копирования конструктора. +Foo f2; +Foo f1 = f2; + +// Вызывает Foo::Foo(const Foo&) или вариант, но копирует только часть 'Foo' из +// 'fooSub'. Любые другие члены 'fooSub' пропускаются. Иногда это ужасное поведение +// называют "object slicing." +FooSub fooSub; +Foo f1 = fooSub; + +// Вызывает Foo::operator=(Foo&) или вариант. +Foo f1; +f1 = f2; + + +// Как по-настоящему очистить контейнер: +class Foo { ... }; +vector<Foo> v; +for (int i = 0; i < 10; ++i) +  v.push_back(Foo()); + +// В следующей точке размер v устанавливается в 0, но деструктор не вызывается +// и не происходит очистка ресурсов! +v.empty(); +v.push_back(Foo());  // Новые значения копируются в первый вставленный Foo + +// Настоящее уничтожение всех значений v. Смотрите раздел о временном объекте +// для объяснения того, как это работает. +v.swap(vector<Foo>()); + +``` +## Дальнейшее чтение: + +Наиболее полное и обновленное руководство по С++ можно найти на +<http://cppreference.com/w/cpp> + +Дополнительные ресурсы могут быть найдены на <http://cplusplus.com> diff --git a/ru-ru/d-ru.html.markdown b/ru-ru/d-ru.html.markdown new file mode 100644 index 00000000..bfa3f085 --- /dev/null +++ b/ru-ru/d-ru.html.markdown @@ -0,0 +1,754 @@ +--- +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 - это С++, сделанный правильно. + +```c +// Welcome to D! Это однострочный комментарий + +/* многострочный +   комментарий  */ + +/+ +    // вложенные комментарии + +    /* еще вложенные +       комментарии */ + +    /+ +        // мало уровней вложенности? Их может быть сколько угодно. +    +/ ++/ + +/* +    Имя модуля. Каждый файл с исходным кодом на D — модуль. +    Если имя не указано явно, то предполагается, что оно совпадает с именем +    файла. Например, для файла "test.d" имя модуля будет "test", если явно +    не указать другое + */ +module app; + +// импорт модуля. Std — пространство имен стандартной библиотеки (Phobos) +import std.stdio; + +// можно импортировать только нужные части, не обязательно модуль целиком +import std.exception : enforce; + +// точка входа в программу — функция main, аналогично C/C++ +void main() +{ +    writeln("Hello, world!"); +} + + + +/*** типы и переменные ***/ + +int a; // объявление переменной типа int (32 бита) +float b = 12.34; // тип с плавающей точкой +double c = 56.78; // тип с плавающей точкой (64 бита) + +/* +    Численные типы в D, за исключением типов с плавающей точкой и типов +    комплексных чисел, могут быть беззнаковыми. +    В этом случае название типа начинается с префикса "u" +*/ +uint d = 10; ulong e = 11; +bool b = true; // логический тип +char d = 'd';  // UTF-символ, 8 бит. D поддерживает UTF "из коробки" +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 + +// Тип переменной, помеченной ключевым словом auto, +// присваивается компилятором исходя из значения этой переменной +auto x = 1;              // Например, тип этой переменной будет int. +auto y = 1.1;            // этой — double +auto z = "Zed is dead!"; // а этой — string + +int[3] arr = [1, 2, 3]; // простой одномерный массив с фиксированным размером +int[] arr2 = [1, 2, 3, 4]; // динамический массив +int[string] aa = ["key1": 5, "key2": 6]; // ассоциативный массив + +/* +   Строки и массивы в D — встроенные типы. Для их использования не нужно +   подключать ни внешние, ни даже стандартную библиотеку, хотя в последней +   есть множество дополнительных инструментов для работы с ними. + */ +immutable int ia = 10;  // неизменяемый тип, +                        // обозначается ключевым словом immutable +ia += 1;                // — вызовет ошибку на этапе компиляции + +// перечислимый (enumerable) тип, +// более правильный способ работы с константами в D +enum myConsts = { Const1, Const2, Const3 }; + +// свойства типов +writeln("Имя типа               : ", int.stringof); // int +writeln("Размер в байтах        : ", int.sizeof);   // 4 +writeln("Минимальное значение   : ", int.min);      // -2147483648 +writeln("Максимальное значение : ", int.max);      // 2147483647 +writeln("Начальное значение     : ", int.init);     // 0. Это значение, +                                                    // присвоенное по умолчанию + +// На самом деле типов в D больше, но все мы здесь описывать не будем, +// иначе не уложимся в Y минут. + + + +/*** Приведение типов ***/ + +// to!(имя типа)(выражение) - для большинства конверсий +import std.conv : to; // функция "to" - часть стандартной библиотеки, а не языка +double d = -1.75; +short s = to!short(d); // s = -1 + +/* +   cast - если вы знаете, что делаете. Кроме того, это единственный способ +   преобразования типов-указателей в "обычные" и наоборот +*/ +void* v; +int* p = cast(int*)v; + +// Для собственного удобства можно создавать псевдонимы +// для различных встроенных объектов +alias int newInt; // теперь можно обращаться к newInt так, как будто бы это int +newInt a = 5; + +alias newInt = int; // так тоже допустимо +alias uint[2] pair; // дать псевдоним можно даже сложным структурам данных + + + +/*** Операторы ***/ + +int x = 10; // присваивание +x = x + 1;  // 11 +x -= 2;     // 9 +x++;        // 10 +++x;        // 11 +x *= 2;     // 22 +x /= 2;     // 11 +x = x ^^ 2; // 121 (возведение в степень) +x ^^= 2;    // 1331 (то же самое) + +string str1 = "Hello"; +string str2 = ", world!"; +string hw = str1 ~ str2; // Конкатенация строк + +int[] arr = [1, 2, 3]; +arr ~= 4; // [1, 2, 3, 4] - добавление элемента в конец массива + + + +/*** Логика и сравнения ***/ + +int x = 0; int y = 1; + +x == y;         // false +x > y;          // false +x < y;          // true +x >= y;         // false +x != y;         // true. ! — логическое "не" +x > 0 || x < 1; // true. || — логическое "или" +x > 0 && x < 1; // false && — логическое "и" +x ^ y           // true; ^ - xor (исключающее "или") + +// Тернарный оператор +auto y = (x > 10) ? 1 : 0; // если x больше 10, то y равен 1, +                           // в противном случае y равен нулю + + +/***  Управляющие конструкции  ***/ + +// if - абсолютно привычен +if (a == 1) { +    // .. +} else if (a == 2) { +    // .. +} else { +    // .. +} + +// switch +switch (a) { +    case 1: +        // делаем что-нибудь +        break; +    case 2: +        // делаем что-нибудь другое +        break; +    case 3: +        // делаем что-нибудь еще +        break; +    default: +        // default обязателен, без него будет ошибка компиляции +        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) { +    // .. +    if (number == 42) { +        break; +    } +} + +while (true) { +    // бесконечный цикл +} + +// do-while +do { +    // .. +} while (a == 10); + +// for +for (int number = 1; number < 11; ++number) { +    writeln(number); // все абсолютно стандартно +} + +for ( ; ; ) { +    // секции могут быть пустыми. Это бесконечный цикл в стиле Си +} + +// foreach - универсальный и самый "правильный" цикл в D +foreach (element; array) { +    writeln(element); // для простых массивов +} + +foreach (key, val; aa) { +    writeln(key, ": ", val); // для ассоциативных массивов +} + +foreach (c; "hello") { +    writeln(c); // hello. Поскольку строки - это вариант массива, +                // foreach применим и к ним +} + +foreach (number; 10..15) { +    writeln(number); // численные интервалы можно указывать явным образом +                     // этот цикл выведет значения с 10 по 14, но не 15, +                     // поскольку диапазон не включает в себя верхнюю границу +} + +// foreach_reverse - в обратную сторону +auto container = [1, 2, 3]; +foreach_reverse (element; container) { +    writefln("%s ", element); // 3, 2, 1 +} + +// foreach в массивах и им подобных структурах не меняет сами структуры +int[] a = [1, 2 ,3 ,4 ,5]; +foreach (elem; array) { +    elem *= 2; // сам массив останется неизменным +} + +writeln(a); // вывод: [1, 2, 3, 4, 5] Т.е изменений нет + +// добавление ref приведет к тому, что массив будет изменяться +foreach (ref elem; array) { +    elem *= 2; +} + +writeln(a); // [2, 4, 6, 8, 10] + +// foreach умеет рассчитывать индексы элементов +int[] a = [1, 2, 3, 4, 5]; +foreach (ind, elem; array) { +    writeln(ind, " ", elem); // через ind - доступен индекс элемента, +                             // а через elem - сам элемент +} + + + +/*** Функции ***/ + +test(42); // Что, вот так сразу? Разве мы где-то уже объявили эту функцию? + +// Нет, вот она. Это не Си, здесь объявление функции не обязательно должно быть +// до первого вызова +int test(int argument) { +    return argument * 2; +} + + +// В D используется единый синтаксис вызова функций +// (UFCS, Uniform Function Call Syntax), поэтому так тоже можно: +int var = 42.test(); + +// и даже так, если у функции нет аргументов: +int var2 = 42.test; + +// можно выстраивать цепочки: +int var3 = 42.test.test; + +/* +    Аргументы в функцию передаются по значению (т.е. функция работает не с +    оригинальными значениями, переданными ей, а с их локальными копиями. +    Исключение составляют объекты классов, которые передаются по ссылке. +    Кроме того, любой параметр можно передать в функцию по ссылке с помощью +    ключевого слова "ref" +*/ +int var = 10; + +void fn1(int arg) { +    arg += 1; +} + +void fn2(ref int arg) { +    arg += 1; +} + +fn1(var); // var все еще = 10 +fn2(var); // теперь var = 11 + +// Возвращаемое значение тоже может быть auto, +// если его можно "угадать" из контекста +auto add(int x, int y) { +    return x + y; +} + +auto z = add(x, y); // тип int - компилятор вывел его автоматически + +// Значения аргументов по умолчанию +float linearFunction(float k, float x, float b = 1) +{ +    return k * x + b; +} + +auto linear1 = linearFunction(0.5, 2, 3); // все аргументы используются +auto linear2 = linearFunction(0.5, 2);    // один аргумент пропущен, но в функции +                                          // он все равно использован и равен 1 + +// допускается описание вложенных функций +float quarter(float x) { +    float doubled(float y) { +        return y * y; +    } + +    return doubled(doubled(x)); +} + +// функции с переменным числом аргументов +int sum(int[] a...) +{ +    int s = 0; +    foreach (elem; a) { +        s += elem; +    } +    return s; +} + +auto sum1 = sum(1); +auto sum2 = sum(1,2,3,4); + +/* +   модификатор "in" перед аргументами функций говорит о том, что функция имеет +    право их только просматривать. При попытке модификации такого аргумента +    внутри функции - получите ошибку +*/ +float printFloat(in float a) +{ +    writeln(a); +} +printFloat(a); // использование таких функций - самое обычное + +// модификатор "out" позволяет вернуть из функции несколько результатов +// без посредства глобальных переменных или массивов +uint remMod(uint a, uint b, out uint modulus) +{ +    uint remainder = a / b; +    modulus = a % b; +    return remainder; +} + +uint modulus;                   // пока в этой переменной ноль +uint rem = remMod(5, 2, modulus); // наша "хитрая" функция, и теперь +                                // в modulus - остаток от деления +writeln(rem, " ", modulus);     // вывод: 2 1 + + + +/*** Структуры, классы, базовое ООП ***/ + +// Объявление структуры. Структуры почти как в Си +struct MyStruct { +    int a; +    float b; + +    void multiply() { +        return a * b; +    } +} + +MyStruct str1; // Объявление переменной с типом MyStruct +str1.a = 10;   // Обращение к полю +str1.b = 20; +auto result = str1.multiply(); +MyStruct str2 = {4, 8}          // Объявление + инициализация  в стиле Си +auto str3 = MyStruct(5, 10);    // Объявление + инициализация  в стиле D + + +// области видимости полей и методов - 3 способа задания +struct MyStruct2 { +    public int a; + +    private: +        float b; +        bool c; + +    protected { +        float multiply() { +            return a * b; +        } +    } +    /* +        в дополнение к знакомым public, private и protected, в D есть еще +        область видимости "package". Поля и методы с этим атрибутом будут +        доступны изо всех модулей, включенных в "пакет" (package), но не +        за его пределами. package - это "папка", в которой может храниться +        несколько модулей. Например, в "import.std.stdio", "std" - это +        package, в котором есть модуль stdio (и еще множество других) +    */ +    package: +        string d; + +    /* помимо этого, имеется еще один модификатор - export, который позволяет +    использовать объявленный с ним идентификатор даже вне самой программы ! +    */ +    export: +         string description; +} + +// Конструкторы и деструкторы +struct MyStruct3 { +    this() { // конструктор. Для структур его не обязательно указывать явно, +             // в этом случае пустой конструктор добавляется компилятором +        writeln("Hello, world!"); +    } + + +    // а вот это конструкция - одна из интересных идиом и представляет собой +    // конструктор копирования, т.е конструктор, возвращающий копию структуры. +    // Работает только в структурах. +    this(this) +    { +        return this; +    } + +    ~this() { // деструктор, также необязателен +        writeln("Awww!"); +    } +} + +// Объявление простейшего класса +class MyClass { +    int a;  // в D по умолчанию данные-члены являются public +    float b; +} + +auto mc = new MyClass(); // ...и создание его экземпляра +auto mc2 = new MyClass; // ... тоже сработает + +// Конструктор +class MyClass2 { +    int a; +    float b; + +    this(int a, float b) { +        this.a = a; // ключевое слово "this" - ссылка на объект класса +        this.b = b; +    } +} + +auto mc2 = new MyClass2(1, 2.3); + +// Классы могут быть вложенными +class Outer +{ +    int m; + +    class Inner +    { +        int foo() +        { +            return m; // можно обращаться к полям "внешнего" класса +        } +    } +} + +// наследование +class Base { +    int a = 1; +    float b = 2.34; + + +    // это статический метод, т.е метод который можно вызывать, обращаясь +    // к классу напрямую, а не через создание экземпляра объекта +    static void multiply(int x, int y) +    { +        writeln(x * y); +    } +} + +Base.multiply(2, 5); // используем статический метод. Результат: 10 + +class Derived : Base { +    string c = "Поле класса - наследника"; + + +    // override означает то, что наследник предоставит свою реализацию метода, +    // переопределив метод базового класса +    override static void multiply(int x, int y) +    { +        super.multiply(x, y);  // super - это ссылка на класс-предок, или базовый класс +        writeln(x * y * 2); +    } +} + +auto mc3 = new Derived(); +writeln(mc3.a); // 1 +writeln(mc3.b); // 2.34 +writeln(mc3.c); // Поле класса - наследника + +// Финальный класс, наследовать от него нельзя +// кроме того, модификатор final работает не только для классов, но и для методов +// и даже для модулей ! +final class FC { +    int a; +} + +class Derived : FC { // это вызовет ошибку +    float b; +} + +// Абстрактный класс не может быть истанциирован, но может иметь наследников +abstract class AC { +    int a; +} + +auto ac = new AC(); // это вызовет ошибку + +class Implementation : AC { +    float b; + +     // final перед методом нефинального класса означает запрет возможности +     // переопределения метода +    final void test() +    { +       writeln("test passed !"); +    } +} + +auto impl = new Implementation(); // ОК + + + +/*** Примеси (mixins) ***/ + +// В D можно вставлять код как строку, если эта строка известна на этапе +// компиляции. Например: +void main() { +   mixin(`writeln("Hello World!");`); +} + +// еще пример +string print(string s) { +   return `writeln("` ~ s ~ `");`; +} + +void main() { +   mixin (print("str1")); +   mixin (print("str2")); +} + + + +/*** Шаблоны ***/ + +/* +    Шаблон функции. Эта функция принимает аргументы разных типов, которые +    подставляются вместо T на этапе компиляции. "T" - это не специальный +    символ, а просто буква. Вместо "T" может быть любое слово, кроме ключевого. + */ +void print(T)(T value) { +   writefln("%s", value); +} + +void main() { +   print(42);     // В одну и ту же функцию передается: целое +   print(1.2);    // ...число с плавающей точкой, +   print("test"); // ...строка +} + +// "Шаблонных" параметров может быть сколько угодно +void print(T1, T2)(T1 value1, T2 value2) { +   writefln(" %s %s", value1, value2); +} + +void main() { +   print(42, "Test"); +   print(1.2, 33); +} + +// Шаблон класса +class Stack(T) +{ +    private: +        T[] elements; + +    public: +        void push(T element) { +            elements ~= element; +        } + +        void pop() { +            --elements.length; +        } + +        T top() const @property { +            return elements[$ - 1]; +        } + +        size_t length() const @property { +            return elements.length; +        } +} + +void main() { +    /* +        восклицательный знак - признак шаблона. В данном случае мы создаем +        класс и указываем, что "шаблонное" поле будет иметь тип string +    */ +   auto stack = new Stack!string; + +   stack.push("Test1"); +   stack.push("Test2"); + +   writeln(stack.top); +   writeln(stack.length); + +   stack.pop; +   writeln(stack.top); +   writeln(stack.length); +} + + + +/*** Диапазоны (ranges) ***/ + +/* +   Диапазоны - это абстракция, которая позволяет легко использовать разные +   алгоритмы с разными структурами данных. Вместо того, чтобы определять свои +   уникальные алгоритмы для каждой структуры, мы можем просто указать для нее +   несколько единообразных функций, определяющих, _как_ мы получаем доступ +   к элементам контейнера, вместо того, чтобы описывать внутреннее устройство +   этого контейнера. Сложно? На самом деле не очень. + +    Простейший вид диапазона - Input Range. Для того, чтобы превратить любой +    контейнер в Input Range, достаточно реализовать для него 3 метода: +    - empty - проверяет, пуст ли контейнер +    - front - дает доступ к первому элементу контейнера +    - popFront - удаляет из контейнера первый элемент +*/ +struct Student +{ +    string name; +    int number; +    string toString() { +        return format("%s(%s)", name, number); +    } +} + +struct School +{ +    Student[] students; +} + +struct StudentRange +{ +    Student[] students; + +    this(School school) { +        this.students = school.students; +    } + +    bool empty() { +        return students.length == 0; +    } + +    Student front() { +        return students[0]; +    } + +    void popFront() { +        students = students[1 .. $]; +    } +} + +void main(){ +    auto school = School([ +            Student("Mike", 1), +            Student("John", 2) , +            Student("Dan", 3) +    ]); +    auto range = StudentRange(school); +    writeln(range);                     // [Mike(1), John(2), Dan(3)] +    writeln(school.students.length);    // 3 +    writeln(range.front());             // Mike(1) +    range.popFront(); +    writeln(range.empty());             // false +    writeln(range);                     // [John(2), Dan(3)] +} +/* +   Смысл в том, что нам не так уж важно внутреннее устройство контейнера, если +   у нас есть унифицированные методы доступа к его элементам. +   Кроме Input Range в D есть и другие типы диапазонов, которые требуют +   реализации большего числа методов, зато дают больше контроля. Это большая +   тема и мы не будем в подробностях освещать ее здесь. + +   Диапазоны - это важная часть D, они используются в нем повсеместно. +*/ +``` +## Что дальше? + +- [Официальный сайт](http://dlang.org/) +- [Онлайн-книга](http://ddili.org/ders/d.en/) +- [Официальная вики](http://wiki.dlang.org/) diff --git a/ru-ru/erlang-ru.html.markdown b/ru-ru/erlang-ru.html.markdown index 99ea79ee..69f81800 100644 --- a/ru-ru/erlang-ru.html.markdown +++ b/ru-ru/erlang-ru.html.markdown @@ -18,7 +18,7 @@ lang: ru-ru  % Пунктуационные знаки, используемые в Erlang:  % Запятая (`,`) разделяет аргументы в вызовах функций, структурах данных и  % образцах. -% Точка (`.`) (с пробелом после них) разделяет функции и выражения в +% Точка (`.`) (с пробелом после неё) разделяет функции и выражения в  % оболочке.  % Точка с запятой (`;`) разделяет выражения в следующих контекстах:  % формулы функций, выражения `case`, `if`, `try..catch` и `receive`. diff --git a/ru-ru/java-ru.html.markdown b/ru-ru/java-ru.html.markdown index b24ad555..a1a5cdfc 100644 --- a/ru-ru/java-ru.html.markdown +++ b/ru-ru/java-ru.html.markdown @@ -9,7 +9,7 @@ filename: LearnJavaRu.java  lang: ru-ru  --- -Java - это объектно ориентированный язык программирования общего назначения, +Java - это объектно-ориентированный язык программирования общего назначения,  основанный на классах и поддерживающий параллельное программирование.  [Подробнее читайте здесь.](http://docs.oracle.com/javase/tutorial/java/index.html) @@ -43,17 +43,41 @@ public class LearnJavaRu {              " Double: " + 3.14 +              " Boolean: " + true); -        // Чтобы напечатать что-либо не заканчивая переводом строки -        // используется System.out.print. +        // Чтобы печатать что-либо, не заканчивая переводом строки, +        // используйте System.out.print.          System.out.print("Hello ");          System.out.print("World"); +        // Используйте System.out.printf() для печати с форматированием +        System.out.printf("pi = %.5f", Math.PI); // => pi = 3.14159          /////////////////////////////////////// -        // Типы и Переменные +        // Переменные          /////////////////////////////////////// +        /* +        *  Объявление переменных +        */          // Переменные объявляются с использованием <тип> <имя> +        int fooInt; +        // Одновременное объявление нескольких переменных одного типа +        // <type> <name1>, <name2>, <name3> +        int fooInt1, fooInt2, fooInt3; + +        /* +        *  Инициализация переменных +        */ + +        // объявление и инициализация переменной <type> <name> = <val> +        int fooInt = 1; +        int fooInt1, fooInt2, fooInt3; +        // инициализация нескольких переменных одного типа +        // <type> <name1>, <name2>, <name3> = <val> +        fooInt1 = fooInt2 = fooInt3 = 1; + +        /* +        *  Типы переменных +        */          // Byte - 8-битное целое число.          // (-128 <= byte <= 127)          byte fooByte = 100; @@ -247,7 +271,7 @@ public class LearnJavaRu {          // Switch Case          // switch работает с типами byte, short, char и int.          // Также он работает с перечислениями, -        // классом String и с некоторыми классами-обертками над +        // классом String (с Java 7) и с некоторыми классами-обертками над          // примитивными типами: Character, Byte, Short и Integer.          int month = 3;          String monthString; @@ -319,7 +343,7 @@ public class LearnJavaRu {          System.out.println("trek info: " + trek.toString());      } // Конец метода main. -} // Конец класса LearnJava. +} // Конец класса LearnJavaRu.  // Вы можете включать другие, не публичные классы в .java файл. @@ -362,7 +386,7 @@ class Bicycle {      // Классы в Java часто реализуют сеттеры и геттеры для своих полей.      // Синтаксис определения метода: -    // <модификатор> <тип возвращаемого значения> <имя>(<аргументы>) +    // <модификатор доступа> <тип возвращаемого значения> <имя метода>(<аргументы>)      public int getCadence() {          return cadence;      } @@ -424,10 +448,10 @@ class PennyFarthing extends Bicycle {  // Интерфейсы  // Синтаксис определения интерфейса:  -// <модификатор доступа> interface <имя> extends <базовый интерфейс> { -//        // Константы -//        // Определение методов. -//} +// <модификатор доступа> interface <имя интерфейса> extends <базовый интерфейс> { +//     // Константы +//     // Определение методов +// }  // Пример - Еда:  public interface Edible { diff --git a/ru-ru/markdown-ru.html.markdown b/ru-ru/markdown-ru.html.markdown index eb8e4881..f71435ea 100644 --- a/ru-ru/markdown-ru.html.markdown +++ b/ru-ru/markdown-ru.html.markdown @@ -2,55 +2,77 @@  language: markdown  contributors:      - ["Dan Turkel", "http://danturkel.com/"] +    - ["Jacob Ward", "http://github.com/JacobCWard/"] +translators:      - ["Pirogov Alexey", "http://twitter.com/alex_pir"] +    - ["Andre Polykanine", https://github.com/Oire"]  filename: markdown-ru.md  lang: ru-ru  ---  Язык разметки Markdown создан Джоном Грубером (англ. John Gruber) -и Аароном Шварцем (англ. Aaron H. Swartz) в 2004 году. +в 2004 году.  Авторы задавались целью создать максимально удобочитаемый  и удобный в публикации облегчённый язык разметки,  пригодный для последующего преобразования в HTML  (а также и в другие форматы). +Также реализации Markdown варьируют в зависимости от парсера. +В этом руководстве будет указано, какие функции универсальны для языка, +а какие зависят от конкретного парсера. + +- [HTML-элементы](#html-elements) +- [Заголовки](#headings) +- [Простейшая стилизация текста](#simple-text-styles) +- [Абзацы](#paragraphs) +- [Списки](#lists) +- [Блоки кода](#code-blocks) +- [Горизонтальный разделитель](#horizontal-rule) +- [Ссылки](#links) +- [Изображения](#images) +- [Разное](#miscellany) + +## HTML-элементы +Markdown является надмножеством HTML, поэтому любой HTML-файл является +корректным документом Markdown. +   ```markdown -<!-- Markdown является надмножеством HTML, поэтому любой HTML-файл является -валидным документом Markdown, что позволяет использовать напрямую +<!-- Это позволяет использовать напрямую  любые элементы HTML-разметки, такие, например, как этот комментарий.    Встроенные в документ HTML-элементы не затрагиваются парсером Markdown -и попадают в итоговый HTML без изменений. Однако, следует понимать, +и попадают в итоговый HTML без изменений. Однако следует понимать,  что эта же особенность не позволяет использовать разметку Markdown внутри  HTML-элементов --> -<!-- Ещё одна особенность формата Markdown состоит в том, что поддерживаемые -возможности разметки зависят от конкретной реализации парсера. В данном -руководстве возможности, поддерживаемые лишь определёнными парсерами, -сопровождаются соответствующими примечаниями. --> - -<!-- Заголовки --> +## Заголовки  -<!-- HTML-элементы от <h1> до <h6> размечаются очень просто: +HTML-элементы от <h1> до <h6> размечаются очень просто:  текст, который должен стать заголовком, предваряется -соответствующим количеством символов "#": --> +соответствующим количеством символов "#": + +```markdown  # Это заголовок h1  ## Это заголовок h2  ### Это заголовок h3  #### Это заголовок h4  ##### Это заголовок h5  ###### Это заголовок h6 +``` +Markdown позволяет размечать заголовки <h1> и <h2> ещё одним способом: -<!-- Markdown позволяет размечать заголовки <h1> и <h2> ещё одним способом: --> +```markdown  Это заголовок h1  ================  А это заголовок h2  ------------------ +``` -<!-- Простейшая стилизация текста --> +## Простейшая стилизация текста -<!-- Текст легко сделать полужирным и/или курсивным: --> +Текст легко сделать полужирным и/или курсивным: +```markdown  *Этот текст будет выведен курсивом.*  _Так же, как этот._ @@ -60,44 +82,58 @@ __И этот тоже.__  ***Полужирный курсив.***  **_И тут!_**  *__И даже здесь!__* +``` -<!-- В Github Flavored Markdown (версии Markdown, использующейся в Github, -для рендеринга Markdown-документов) текст можно сделать зачёркнутым: --> +В Github Flavored Markdown, стандарте, который используется в Github, +текст также можно сделать зачёркнутым: +```markdown  ~~Зачёркнутый текст.~~ +``` + +## Абзацы + +Абзацами являются любые строки, следующие друг за другом. +Разделяются же абзацы одной или несколькими пустыми строками: -<!-- Абзацами являются любые строки, следующие друг за другом. -Разделяются же абзацы одной или несколькими пустыми строками: --> +```markdown +Это абзац. Я печатаю в абзаце, разве это не прикольно? -Это абзац. Всё предельно просто. +А тут уже абзац №2. +Эта строка всё ещё относится к абзацу №2! -А тут уже параграф №2. -Эта строка всё ещё относится к параграфу №2! +О, а вот это уже абзац №3! +``` -О, а вот это уже параграф №3! +Для вставки принудительных переносов можно завершить абзац двумя дополнительными пробелами: -<!-- Для вставки принудительных переносов можно использовать HTML-тэг <br/>: --> +```markdown +Эта строка завершается двумя пробелами (выделите, чтобы увидеть!).   -Принудительный <br/> перенос! +Над этой строкой есть <br />! +``` -<!-- Цитаты размечаются с помощью символа ">": --> +Цитаты размечаются с помощью символа «>»: +```markdown  > Это цитата. В цитатах можно -> принудительно переносить строки, вставляя ">" в начало каждой следующей строки. А можно просто оставлять достаточно длинными, и такие длинные строки будут перенесены автоматически. +> принудительно переносить строки, вставляя «>» в начало каждой следующей строки. А можно просто оставлять их достаточно длинными, и такие длинные строки будут перенесены автоматически.  > Разницы между этими двумя подходами к переносу строк нет, коль скоро -> каждая строка начинается с символа ">" +> каждая строка начинается с символа «>»  > А ещё цитаты могут быть многоуровневыми:  >> как здесь  >>> и здесь :)  > Неплохо? +``` -<!-- Списки --> -<!-- Маркированные списки размечаются вставкой в начало каждого элемента -одного из символов "*", "+" или "-": -(символ должен быть одним и тем же для всех элементов) --> +## Списки +Маркированные списки размечаются вставкой в начало каждого элемента +одного из символов «*», «+» или «-»: +(символ должен быть одним и тем же для всех элементов) +```markdown  * Список,  * Размеченный  * Звёздочками @@ -113,167 +149,207 @@ __И этот тоже.__  - Список,  - Размеченный  - Дефисами +``` -<!-- В нумерованных списках каждая строка начинается -с числа и точки вслед за ним: --> +В нумерованных списках каждая строка начинается +с числа и точки вслед за ним: +```markdown  1. Первый элемент  2. Второй элемент  3. Третий элемент +``` -<!-- Заметьте, нумеровать элементы корректно необязательно. Достаточно указать -любое число в начале каждого элемента и рендер пронумерует элементы сам! -Правда, злоупотреблять этим не стоит :) --> +Заметьте, нумеровать элементы корректно необязательно. Достаточно указать +любое число в начале каждого элемента, и парсер пронумерует элементы сам! +Правда, злоупотреблять этим не стоит :) +```markdown  1. Первый элемент  1. Второй элемент  1. Третий элемент -<!-- (Этот список будет отрендерен так же, как и предыдущий!) --> +``` +(Этот список будет отображён так же, как и предыдущий!) -<!-- Списки могут быть вложенными: --> +Списки могут быть вложенными: +```markdown  1. Введение  2. Начало работы  3. Примеры использования      * Простые      * Сложные  4. Заключение +``` + +Можно даже делать списки задач. Блок ниже создаёт HTML-флажки.  -<!-- Блоки с исходным кодом --> -<!-- Фрагменты исходного кода выделяются очень просто - каждая строка блока должна иметь отступ в четыре пробела либо в один символ табуляции --> +```markdown +Для отметки флажка используйте «x» +- [ ] Первая задача +- [ ] Вторая задача +Этот флажок ниже будет отмечен +- [x] Задача была завершена +``` +## Блоки кода + +Фрагменты исходного кода (обычно отмечаемые тегом `<code>`) выделяются просто: +каждая строка блока должна иметь отступ в четыре пробела либо в один символ табуляции. + +```markdown      Это код, -    причём - многострочный +    причём многострочный +``` -<!-- Дополнительные отступы в коде следует делать с помощью четырёх пробелов: --> +Вы также можете делать дополнительные отступы, добавляя символы табуляции +или по четыре пробела: +```markdown      my_array.each do |item|          puts item      end +``` -<!-- Иногда бывает нужно вставить фрагмент кода прямо в строку текста, +Иногда бывает нужно вставить фрагмент кода прямо в строку текста,  не выделяя код в блок. Для этого фрагменты кода нужно обрамлять -символами "`": --> +символами «`»: -Например, можно выделить имя функции `go_to()` прямо посреди текста. +```markdown +Ваня даже не знал, что делает функция `go_to()`! +``` -<!-- Github Flavored Markdown позволяет указать для блока кода синтаксис оного. -В этом случае синтаксис внутри блока будет подсвечен. Пример: --> +В Github Flavored Markdown для блоков кода можно использовать +специальный синтаксис: -\`\`\`ruby <!-- Только нужно будет убрать символы "\", оставив лишь "```ruby" --> +<pre> +<code class="highlight">```ruby  def foobar -    puts "Hello world!" +    puts "Привет, мир!"  end -\`\`\` <!-- И здесь тоже backslashes нужно убрать, т.е. оставить "```" --> +```</code></pre> -<-- Обратите внимание: фрагмент, указанный выше, не предваряется отступами, -поскольку Github сам в состоянии определить границы блока - по строкам "```" --> +Во фрагменте, приведённом выше, отступ не требуется. +Кроме того, Github подсветит синтаксис языка, указанного после \`\`\` -<!-- Горизонтальный разделитель (<hr />) --> -<!-- Разделители добавляются вставкой строки из трёх и более -(одинаковых) символов "*" или "-": --> +## Горизонтальный разделитель +Разделители (`<hr>`) добавляются вставкой строки из трёх и более +(одинаковых) символов «*» или «-», с пробелами или без них: + +```markdown  ***  --- -- - - <!-- между символами допустимы пробелы --> +- - -  **************** +``` + +## Ссылки -<!-- Ссылки --> -<!-- Одной из сильных сторон Markdown можно смело считать то, +Одной из сильных сторон Markdown можно смело считать то,  как просто размечаются гиперссылки. Для создания ссылки укажите  текст ссылки, заключив его в квадратные скобки, -и сразу после - url, заключенный в "круглые" --> +и сразу после — URL-адрес, заключенный в круглые +```markdown  [Ссылка!](http://test.com/) +``` +Также для ссылки можно указать всплывающую подсказку (`title`), используя +кавычки внутри круглых скобок: -<!-- Также для ссылки можно указать всплывающую подсказку: --> - +```markdown  [Ссылка!](http://test.com/ "Ссылка на Test.com") +``` +Относительные пути тоже возможны: -<!-- В url можно использовать относительные пути: --> - +```markdown  [Перейти к музыке](/music/). +``` -<!-- Markdown позволяет размечать ссылку в виде сноски: --> +Markdown также позволяет размечать ссылку в виде сноски: -[Здесь][link1] высможете узнать больше! -А можно кликнуть [сюда][foobar], если очень хочется. +<pre><code class="highlight">[<span class="nv">Щёлкните эту ссылку</span>][<span class="ss">link1</span>] для подробной информации! +[<span class="nv">Также посмотрите эту ссылку,</span>][<span class="ss">foobar</span>] если хотите. -<!-- где-нибудь внизу --> -[link1]: http://test.com/ "Круто!" -[foobar]: http://foobar.biz/ "Тоже хорошо!" +[<span class="nv">link1</span>]: <span class="sx">http://test.com/</span> <span class="nn">"Круто!"</span> +[<span class="nv">foobar</span>]: <span class="sx">http://foobar.biz/</span> <span class="nn">"Нормально!"</span></code></pre> -<!-- Примечания: -- Подсказка может быть заключена в одинарные кавычки вместо двойных, -  а также в круглые скобки. -- Сноска может находиться в любом месте документа и может иметь -идентификатор (далее ID) произвольной длины, -лишь бы это ID был уникальным. --> +`Title` также может быть в одинарных кавычках или круглых скобках, а также +отсутствовать вовсе. Ссылки на сноски могут быть в любом месте документа, +а идентификаторы могут быть какими угодно, лишь бы они были уникальными. -<!-- Также при разметке ссылок-сносок можно опустить ID, -если текст ссылки уникален в пределах документа: --> +Существует также неявное именование, когда ссылка является идентификатором. -Ссылка на [Google][]. +<pre><code class="highlight">[<span class="nv">Это</span>][] ссылка. -[google]: http://google.com/ +[<span class="nv">это</span>]: <span class="sx">http://thisisalink.com/</span></code></pre> -<!-- Правда, эта возможность не очень распространена. --> +Правда, эта возможность не очень распространена. -<!-- Изображения --> -<!-- Разметка изображений очень похожа на разметку ссылок. -Нужно всего лишь добавить "!" перед ссылкой! --> +## Изображения +Разметка изображений очень похожа на разметку ссылок. +Нужно всего лишь добавить перед ссылкой восклицательный знак! +```markdown   +``` +Изображения тоже могут быть оформлены, как сноски. -<!-- Изображения тоже могут быть оформлены, как сноски: --> - -![Альтернативный текст][myimage] - -![То же изображение ещё раз][myimage] - -[myimage]: relative/urls/cool/image.jpg "подсказка" +<pre><code class="highlight">![<span class="nv">Это альтернативный текст.</span>][<span class="ss">myimage</span>] -<!-- Ещё немного ссылок: --> -<!-- Автоссылки --> +[<span class="nv">myimage</span>]: <span class="sx">relative/urls/cool/image.jpg</span> <span class="nn">"Если нужна подсказка, её можно добавить"</span></code></pre> +## Разное +### Автоссылки +```markdown  Ссылка вида <http://testwebsite.com/> эквивалентна  [http://testwebsite.com/](http://testwebsite.com/) +``` -<!-- Автоссылки для адресов электронной почты --> +### Автоссылки для адресов электронной почты +```markdown  <foo@bar.com> +``` + +### Экранирование символов -<!-- Экранирование символов --> +```markdown +Я хочу напечатать *текст, заключённый в звёздочки*, но я не хочу, +чтобы он был курсивным. Тогда я делаю так: +\*Текст, заключённый в звёздочки\* +``` -<!-- Может потребоваться вставить спецсимвол в текст "как есть", -т.е. защитить его от обработки парсером. -Такой символ должен быть "экранирован" с помощью обратной косой черты -(символа "\"): --> +### Клавиши на клавиатуре +В Github Flavored Markdown для представления клавиш на клавиатуре +вы можете использовать тег `<kbd>`. -\*текст, заключённый в звёздочки!\* +```markdown +Ваш компьютер завис? Попробуйте нажать +<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd> +``` -<!-- Таблицы --> -<!-- Таблицы официально поддерживаются только в Github Flavored Markdown, +### Таблицы +Таблицы официально поддерживаются только в GitHub Flavored Markdown,  да и синтаксис имеют не слишком удобный. -Но если очень нужно, размечайте таблицы так: --> +Но если очень нужно, размечайте таблицы так: +```markdown  | Столбец 1    | Столбец 2    | Столбец 3    |  | :----------- | :----------: | -----------: |  | Выравнивание | Выравнивание | Выравнивание |  | влево        | по центру    | вправо       | +``` +Или более компактно -<!-- Или более компактно --> - -Колонка 1|Колонка 2|Колонка 3 +```markdown +Столбец 1|Столбец 2|Столбец 3  :--|:-:|--:  Выглядит|это|страшновато... - -<!-- Ну вот и всё! --> -  ``` -За более подробной информацией обращайтесь к [статье](http://daringfireball.net/projects/markdown/syntax) Джона Грубера о синтаксисе Markdown. +Ну вот и всё! -Также часто бывает полезной отличная ["шпаргалка"](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) по Markdown от Adam Pritchard. +За более подробной информацией обращайтесь к [статье](http://daringfireball.net/projects/markdown/syntax) Джона Грубера о синтаксисе Markdown. -Если вдруг встретите ошибки в переводе или же захотите его дополнить, делайте pull requests - авторы всегда рады обратной связи! +Также часто бывает полезной отличная ["шпаргалка"](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) по Markdown от Адама Притчарда. diff --git a/ru-ru/objective-c-ru.html.markdown b/ru-ru/objective-c-ru.html.markdown index 8eac4ddb..d60db1d8 100644 --- a/ru-ru/objective-c-ru.html.markdown +++ b/ru-ru/objective-c-ru.html.markdown @@ -381,20 +381,21 @@ if ([myClass respondsToSelector:selectorVar]) { // Проверяет содер      NSLog(@"MyClass не содержит метод: %@", NSStringFromSelector(selectedVar));  } -// Имплементируйте методы в файле МойКласс.m: +// Имплементируйте методы в файле MyClass.m:  @implementation MyClass {      long distance; // Переменная экземпляра с закрытым (private) доступом      NSNumber height;  } -// To access a public variable from the interface file, use '_' followed by variable name: -_count = 5; // References "int count" from MyClass interface -// Access variables defined in implementation file: -distance = 18; // References "long distance" from MyClass implementation -// To use @property variable in implementation, use @synthesize to create accessor variable: -@synthesize roString = _roString; // _roString available now in @implementation +// Для доступа к public переменной, объявленной в интерфейсе, используйте '_' перед названием переменной: +_count = 5; // Ссылается на "int count" из интерфейса MyClass +// Получение доступа к переменной, объявленной в реализации происходит следующим образом: +distance = 18; // Ссылается на "long distance" из реализации MyClass +// Для использования в иплементации переменной, объявленной в интерфейсе с помощью @property, +// следует использовать @synthesize для создания переменной аксессора: +@synthesize roString = _roString; // Теперь _roString доступна в @implementation (реализации интерфейса) -// Called before calling any class methods or instantiating any objects +// Вызывается в первую очередь, перед вызовом других медотов класса или инициализации других объектов  + (void)initialize   {      if (self == [MyClass class]) { @@ -505,10 +506,10 @@ distance = 18; // References "long distance" from MyClass implementation  @end -// Теперь, если мы хотели создать грузовой объект, мы должны вместо создания подкласса класса Car, как это будет -// изменять функциональность Car чтобы вести себя подобно грузовику. Но давайте посмотрим, если мы хотим только добавить -// функциональность в существующий Car. Хороший пример должен быть чистить автомобиль. Итак мы создадим -// категорию для добавления его очистительных методов: +// Теперь, если мы хотим создать объект Truck - грузовик, мы должны создать подкласс класса Car, что +// изменит функционал Car и позволит вести себя подобно грузовику. Но что, если мы хотим только добавить +// определенный функционал в уже существующий класс Car? Например - чистка автомобиля. Мы просто создадим +// категорию, которая добавит несколько методов для чистки автомобиля в класс Car:  // @interface ИмяФайла: Car+Clean.h (ИмяБазовогоКласса+ИмяКатегории.h)  #import "Car.h" // Убедитесь в том, что базовый класс импортирован для расширения. @@ -794,7 +795,7 @@ MyClass *arcMyClass = [[MyClass alloc] init];  // weakVar-свойство автоматически примет значение nil,  // во избежание падения приложения  @property (strong) MyClass *strongVar; // 'strong' принимает право на владение -// объектом. Гарантирует, что объект останится в памяти для использования +// объектом. Гарантирует, что объект останется в памяти для использования  // Для обычных переменных (не объявленных с помощью @property), используйте  // следующий способ: diff --git a/ru-ru/perl-ru.html.markdown b/ru-ru/perl-ru.html.markdown new file mode 100644 index 00000000..a907ba41 --- /dev/null +++ b/ru-ru/perl-ru.html.markdown @@ -0,0 +1,195 @@ +--- +category: language +language: perl +filename: learnperl-ru.pl +contributors: +    - ["Korjavin Ivan", "http://github.com/korjavin"] +translators: +    - ["Elena Bolshakova", "http://github.com/liruoko"] +lang: ru-ru +--- + +Perl 5 -- высокоуровневый мощный язык с 25-летней историей.  +Особенно хорош для обработки разнообразных текстовых данных.  + +Perl 5 работает более чем на 100 платформах, от портативных устройств +до мейнфреймов, и подходит как для быстрого прототипирования,  +так и для крупных проектов.  + +```perl +# Комментарии начинаются с символа решетки. + + +#### Типы переменных в Perl + +#  Скалярные переменные начинаются с знака доллара $. +#  Имя переменной состоит из букв, цифр и знаков подчеркивания,  +#  начиная с буквы или подчеркивания.  + +### В Perl три основных типа переменных: скаляры, массивы, хеши. + +## Скаляры +#  Скаляр хранит отдельное значение: +my $animal = "camel"; +my $answer = 42; + +# Скаляры могут быть строками, целыми и вещественными числами. +# Когда требуется, Perl автоматически выполняет преобразования к нужному типу. + +## Массивы +#  Массив хранит список значений: +my @animals = ("camel", "llama", "owl"); +my @numbers = (23, 42, 69); +my @mixed   = ("camel", 42, 1.23); + + +## Хеши +#   Хеш хранит набор пар ключ/значение: + +my %fruit_color = ("apple", "red", "banana", "yellow"); + +#  Можно использовать оператор "=>" для большей наглядности: + +my %fruit_color = ( +        apple  => "red", +        banana => "yellow", +        ); + +# Важно: вставка и поиск в хеше выполняются за константное время,  +# независимо от его размера. + +# Скаляры, массивы и хеши подробно описаны в разделе perldata +# (perldoc perldata). + +# Более сложные структуры данных можно получить, если использовать ссылки. +# С помощью ссылок можно получить массив массивов хешей, в которых хранятся другие хеши. + +#### Условные операторы и циклы + +# В Perl есть большинсво привычных условных и циклических конструкций. + +if ( $var ) { +    ... +} elsif ( $var eq 'bar' ) { +    ... +} else { +    ... +} + +unless ( condition ) { +                   ... +               } +# Это более читаемый вариант для "if (!condition)" + +# Специфические Perl-овые пост-условия:  +print "Yow!" if $zippy; +print "We have no bananas" unless $bananas; + +#  while +  while ( condition ) { +                   ... +               } + + +# for, foreach +for ($i = 0; $i <= $max; $i++) { +                   ... +               } + +foreach (@array) { +                   print "This element is $_\n"; +               } + +for my $el (@array) { +                   print "This element is $el\n"; +               } + +#### Регулярные выражения + +# Регулярные выражения занимают важное место в Perl-е, +# и подробно описаны в разделах документации perlrequick, perlretut и других. +# Вкратце: + +# Сопоставление с образцом +if (/foo/)       { ... }  # выполняется, если $_ содержит "foo" +if ($a =~ /foo/) { ... }  # выполняется, если $a содержит "foo" + +# Простые замены + +$a =~ s/foo/bar/;         # заменяет foo на bar в строке $a +$a =~ s/foo/bar/g;        # заменяет ВСЕ ВХОЖДЕНИЯ foo на bar в строке $a + + +#### Файлы и ввод-вывод + +# Открыть файл на чтение или запись можно с помощью функции "open()". + +open(my $in,  "<",  "input.txt")  or die "Can't open input.txt: $!"; +open(my $out, ">",  "output.txt") or die "Can't open output.txt: $!"; +open(my $log, ">>", "my.log")     or die "Can't open my.log: $!"; + +# Читать из файлового дескриптора можно с помощью оператора "<>".   +# В скалярном контексте он читает одну строку из файла, в списковом --  +# читает сразу весь файл, сохраняя по одной строке в элементе массива: + +my $line  = <$in>; +my @lines = <$in>; + +#### Подпрограммы (функции) + +# Объявить функцию просто: + +sub logger { +    my $logmessage = shift; +    open my $logfile, ">>", "my.log" or die "Could not open my.log: $!"; +    print $logfile $logmessage; +} + +# Теперь можно использовать эту функцию так же, как и встроенные: + +logger("We have a logger subroutine!"); +``` + +#### Perl-модули + +Perl-овые модули предоставляют широкий набор функциональности,  +так что вы можете не изобретать заново велосипеды, а просто скачать  +нужный модуль с CPAN (http://www.cpan.org/).  +Некоторое количество самых полезных модулей включено в стандартную  +поставку Perl. + +Раздел документации perlfaq содержит вопросы и ответы о многих частых  +задачах, и часто предлагает подходящие CPAN-модули. + + +#### Unicode + +Вам наверняка понадобится работать с не-ASCII текстами. +Добавьте эти прагмы в начало скрипта: + +```perl +use utf8; +use open ':std' => ':utf8'; +``` + +Подробнее читайте в perldoc, разделы perlunicode и open. + + +#### strict, warnings + +Прагмы strict и warnings включают полезные проверки во время компиляции: + +```perl +use strict; +use warnings; +``` + +Подробнее смотрите perldoc strict и perldoc warnings. + + +#### Смотрите также + + - [perl-tutorial](http://perl-tutorial.org/) + - [обучающий раздел на www.perl.com](http://www.perl.org/learn.html) + - [perldoc в вебе](http://perldoc.perl.org/) + - встроенная справка : `perldoc perlintro` diff --git a/ru-ru/php-ru.html.markdown b/ru-ru/php-ru.html.markdown index 37b6a86e..42c4d360 100644 --- a/ru-ru/php-ru.html.markdown +++ b/ru-ru/php-ru.html.markdown @@ -32,7 +32,7 @@ print('Hello '); // Напечатать "Hello " без перевода стр  // () необязательно применять для print и echo  echo "World\n"; // Напечатать "World" и перейти на новую строку. -// (все утверждения должны заканчиваться ;) +// (все утверждения должны заканчиваться точкой с запятой)  // Любые символы за пределами закрывающего тега выводятся автоматически:  ?> @@ -45,8 +45,8 @@ Hello World Again!   */  // Переменные начинаются с символа $. -// Правильное имя переменной начинается с буквы или знака подчеркивания, -// и может содержать любые цифры, буквы, или знаки подчеркивания. +// Правильное имя переменной начинается с буквы или символа подчеркивания, +// за которым следует любое количество букв, цифр или символов подчеркивания.  // Не рекомендуется использовать кириллические символы в именах (прим. пер.)  // Логические значения нечувствительны к регистру @@ -55,7 +55,7 @@ $boolean = false; // или FALSE или False  // Целые числа  $int1 = 12;   // => 12 -$int2 = -12;  // => -12- +$int2 = -12;  // => -12  $int3 = 012;  // => 10 (ведущий 0 обозначает восьмеричное число)  $int4 = 0x0F; // => 15 (ведущие символы 0x означают шестнадцатеричное число) @@ -87,7 +87,7 @@ $dbl_quotes = "This is a $sgl_quotes."; // => 'This is a $String.'  $escaped   = "This contains a \t tab character.";  $unescaped = 'This just contains a slash and a t: \t'; -// Заключайте переменные в фигурные скобки если это необходимо +// Заключайте переменные в фигурные скобки, если это необходимо  $money = "I have $${number} in the bank.";  // Начиная с PHP 5.3, синтаксис nowdocs может использоваться для @@ -106,6 +106,9 @@ END;  // Строки соединяются при помощи .  echo 'This string ' . 'is concatenated'; +// echo можно передавать строки как параметры +echo 'Multiple', 'Parameters', 'Valid'; // печатает 'MultipleParametersValid' +  /********************************   * Константы @@ -114,18 +117,19 @@ echo 'This string ' . 'is concatenated';  // Константа определяется при помощи define()  // и никогда не может быть изменена во время выполнения программы! -// Правильное имя константы начинается с буквы или символа подчеркивания, -// и содержит любое колличество букв, цифр и знаков подчеркивания. +// Правильное имя константы начинается с буквы или символа подчеркивания +// и содержит любое колличество букв, цифр или символов подчеркивания.  define("FOO", "something"); -// Доступ к константе возможен через прямое указание её имени -echo 'This outputs '.FOO; +// Доступ к константе возможен через прямое указание её имени без знака $ +echo FOO; // печатает 'something' +echo 'This outputs ' . FOO; // печатает 'This ouputs something'  /********************************   * Массивы   */ -// Все массивы в PHP - это ассоциативные массивы или хеши, +// Все массивы в PHP - это ассоциативные массивы  // Ассоциативные массивы, известные в других языках как HashMap. @@ -189,7 +193,7 @@ $b = '0';  $c = '1';  $d = '1'; -// Утверждение (assert) выдает предупреждение если аргумент не true +// Утверждение (assert) выдает предупреждение, если его аргумент не true  // Эти сравнения всегда будут истинными, даже если типы будут различаться  assert($a == $b); // "равно" @@ -284,35 +288,35 @@ This is displayed otherwise.  // Использование switch.  switch ($x) {      case '0': -        print 'Switch does type coercion'; -        break; // You must include a break, or you will fall through -               // to cases 'two' and 'three' +        print 'Switch использует неточное сравнение'; +        break; // вы должны использовать break, иначе PHP будет продолжать +               // исполнять команды следующих секций case 'two' и 'three'      case 'two':      case 'three': -        // Do something if $variable is either 'two' or 'three' +        // делаем что-то, если $x == 'two' или $x == 'three'          break;      default: -        // Do something by default +        // делаем что-то по умолчанию  }  // Циклы: while, do...while и for  $i = 0;  while ($i < 5) {      echo $i++; -}; // Prints "01234" +}; // печатает "01234"  echo "\n";  $i = 0;  do {      echo $i++; -} while ($i < 5); // Prints "01234" +} while ($i < 5); // печатает "01234"  echo "\n";  for ($x = 0; $x < 10; $x++) {      echo $x; -} // Напечатает "0123456789" +} // печатает "0123456789"  echo "\n"; @@ -335,17 +339,17 @@ echo "\n";  $i = 0;  while ($i < 5) {      if ($i === 3) { -        break; // Exit out of the while loop +        break; // выйти из цикла while      }      echo $i++;  } // Напечатает "012"  for ($i = 0; $i < 5; $i++) {      if ($i === 3) { -        continue; // Skip this iteration of the loop +        continue; // пропустить текущую итерацию цикла      }      echo $i; -} // Напечатает "0124" +} // печатает "0124"  /******************************** @@ -360,7 +364,7 @@ function my_function () {  echo my_function(); // => "Hello"  // Правильное имя функции начинается с буквы или символа подчеркивания -// и состоит из букв, цифр или знаков подчеркивания. +// и состоит из букв, цифр или символов подчеркивания.  function add ($x, $y = 1) { // $y по умолчанию равно 1    $result = $x + $y; @@ -447,7 +451,7 @@ $value = include 'my-include.php';  class MyClass  { -    const MY_CONST      = 'value'; // A constant +    const MY_CONST      = 'value'; // Константа      static $staticVar   = 'static'; @@ -656,7 +660,10 @@ $cls = new SomeOtherNamespace\MyClass();  ```  ## Смотрите также: -Посетите страницу [официальной документации PHP](http://www.php.net/manual/) для справки.  +Посетите страницу [официальной документации PHP](http://www.php.net/manual/) для справки. +  Если вас интересуют полезные приемы использования PHP посетите [PHP The Right Way](http://www.phptherightway.com/). +  Если вы раньше пользовались языком с хорошей организацией пакетов, посмотрите [Composer](http://getcomposer.org/). +  Для изучения стандартов использования языка посетите PHP Framework Interoperability Group's [PSR standards](https://github.com/php-fig/fig-standards).  diff --git a/ru-ru/python3-ru.html.markdown b/ru-ru/python3-ru.html.markdown index 2a7b3f7b..2b6b59a7 100644 --- a/ru-ru/python3-ru.html.markdown +++ b/ru-ru/python3-ru.html.markdown @@ -549,7 +549,7 @@ Human.grunt() #=> "*grunt*"  # Вы можете импортировать модули  import math -print(math.sqrt(16)) #=> 4 +print(math.sqrt(16)) #=> 4.0  # Вы можете импортировать отдельные функции модуля  from math import ceil, floor diff --git a/ru-ru/tmux-ru.html.markdown b/ru-ru/tmux-ru.html.markdown new file mode 100644 index 00000000..aa7545cc --- /dev/null +++ b/ru-ru/tmux-ru.html.markdown @@ -0,0 +1,252 @@ +--- +category: tool +tool: tmux +contributors: +  - ["mdln", "https://github.com/mdln"] +translators: +  - ["Davydov Anton", "https://github.com/davydovanton"] +filename: LearnTmux-ru.txt +lang: ru-ru +--- + +[tmux](http://tmux.sourceforge.net) - терминальный мультиплексор. +Он позволяет создавать, получать доступ и контролировать любое +количество терминалов из единого окна. +Сессия tmux также может быть свернута в фоновый режим, и она +будет работать в фоне, а после к ней можно будет подключиться. + + +``` + +  tmux [command]     # Запуск команды 'tmux' +                     # без какой-либо команды создаст новую сессию + +    new              # Создать новую сессию +     -s "Session"    # Создать именованную сессию +     -n "Window"     # Создать именованное окно +     -c "/dir"       # Запустить сессию в конкретной директории + +    attach           # Подключиться к последней/существующей сессии +     -t "№"          # Подключиться к определенной сессии +     -d              # Завершить определенную сессию + +    ls               # Список открытых сессий +     -a              # Список всех открытых сессий + +    lsw              # Список окон +     -a              # Список всех окон +     -s              # Список всех окон в сессии + +    lsp              # Список панелей +     -a              # Список всех панелей +     -s              # Список всех панелей в сессии +     -t              # Список всех панелей для конкретного объекта + +    kill-window      # Закрыть текущее окно +     -t "#"          # Закрыть конкретное окно +     -a              # Закрыть все окна +     -a -t "#"       # Закрыть все окна, кроме конкретного + +    kill-session     # Завершить текущую сессию +     -t "#"          # Завершить конкретную сессию +     -a              # Завершить все сессии +     -a -t "#"       # Завершить все сессии, кроме конкретной + +``` + + +### "Горячие" клавиши + +Способ, с помощью которого контролируется любая tmux +сессия, - комбинация клавиш, называемая 'Префиксом'. + +``` +---------------------------------------------------------------------- +  (C-b) = Ctrl + b    # 'Префикс' необходим для +                      # использования горячих клавиш + +  (M-1) = Meta + 1 -или- Alt + 1 +---------------------------------------------------------------------- + +  ?                    # Список всех горячих клавиш +  :                    # Начать ввод в командной строке tmux +  r                    # Принудительная перерисовка текущего клиента +  c                    # Создать новое окно + +  !                    # Переместить текущую панель в отдельное окно +  %                    # Разделить текущую панель на две: левую и правую +  "                    # Разделить текущую панель на две: верхнюю и нижнюю + +  n                    # Переместиться на следующее окно +  p                    # Переместиться на предыдущее окно +  {                    # Заменить текущую панель на предыдущую +  }                    # Заменить текущую панель на следующую + +  s                    # Интерактивный выбор запущенных сессий +  w                    # Интерактивный выбор текущего окна +  от 0 до 9            # Выбрать окно номер 0..9 + +  d                    # Отключить текущий клиент +  D                    # Выбрать клиент, который будет отключен + +  &                    # Закрыть текущее окно +  x                    # Закрыть текущую панель + +  Стрелки вверх, вниз  # Переместиться на панель выше, ниже, левее +  влево, вправо        # или правее + +  M-1 to M-5           # Расставить панели: +                         # 1) выровнять по горизонтали +                         # 2) выровнять по вертикали +                         # 3) основное горизонтально +                         # 4) основное вертикально +                         # 5) мозаикой + +  C-Up, C-Down         # Изменение размера текущей панели с шагом в одну +  C-Left, C-Right      # колонку + +  M-Up, M-Down         # Изменение размера текущей панели с шагом в пять +  M-Left, M-Right      # колонок + +``` + + +### Настройка ~/.tmux.conf + +Файл tmux.conf может быть использован для автоматической установки +опций при старте, как, например, .vimrc или init.el. + +``` +# Пример файла tmux.conf +# 2014.10 + + +### Общее +########################################################################### + +# Включить поддержку UTF-8 +setw -g utf8 on +set-option -g status-utf8 on + +# Установить лимит истории +set -g history-limit 2048 + +# Порядковый номер первой панели +set -g base-index 1 + +# Включить поддержку мыши +set-option -g mouse-select-pane on + +# Принудительная перезагрузка конфигурационного файла +unbind r +bind r source-file ~/.tmux.conf + + +### Горячие клавиши +########################################################################### + +# Отменить комбинацию C-b как стандартный префикс +unbind C-b + +# Установить новую комбинацию как префикс +set-option -g prefix ` + +# Вернуть предыдущее окно, если префикс был нажат два раза +bind C-a last-window +bind ` last-window + +# Разрешить замену C-a и ` на F11/F12 +bind F11 set-option -g prefix C-a +bind F12 set-option -g prefix ` + +# Настройки клавиш +setw -g mode-keys vi +set-option -g status-keys vi + +# Перемещение между панелями, как в vim +bind h select-pane -L +bind j select-pane -D +bind k select-pane -U +bind l select-pane -R + +# Переключить/Заменить окно +bind e previous-window +bind f next-window +bind E swap-window -t -1 +bind F swap-window -t +1 + +# Комманды, упрощающие разделением панелей +bind = split-window -h +bind - split-window -v +unbind '"' +unbind % + +# Активировать центральную сессию (когда вложенный tmux) для отправки команд +bind a send-prefix + + +### Цветовая схема +########################################################################### + +# Цветовая палитра строки состояния +set-option -g status-justify left +set-option -g status-bg black +set-option -g status-fg white +set-option -g status-left-length 40 +set-option -g status-right-length 80 + +# Цветовая палитра окантовки панели +set-option -g pane-active-border-fg green +set-option -g pane-active-border-bg black +set-option -g pane-border-fg white +set-option -g pane-border-bg black + +# Цветовая палитра сообщений +set-option -g message-fg black +set-option -g message-bg green + +# Цветовая палитра статус окна +setw -g window-status-bg black +setw -g window-status-current-fg green +setw -g window-status-bell-attr default +setw -g window-status-bell-fg red +setw -g window-status-content-attr default +setw -g window-status-content-fg yellow +setw -g window-status-activity-attr default +setw -g window-status-activity-fg yellow + + +### Интерфейс +########################################################################### + +# Уведомления +setw -g monitor-activity on +set -g visual-activity on +set-option -g bell-action any +set-option -g visual-bell off + +# Автоматическая установка заголовка окна +set-option -g set-titles on +set-option -g set-titles-string '#H:#S.#I.#P #W #T' # window number,program name,active (or not) + +# Настройки строки состояния +set -g status-left "#[fg=red] #H#[fg=green]:#[fg=white]#S#[fg=green] |#[default]" + +# Показывать системные характеристики в статусбаре +# Требует https://github.com/thewtex/tmux-mem-cpu-load/ +set -g status-interval 4 +set -g status-right "#[fg=green] | #[fg=white]#(tmux-mem-cpu-load)#[fg=green] | #[fg=cyan]%H:%M #[default]" + +``` + +### Ссылки + +[Tmux | Домашняя страница](http://tmux.sourceforge.net) + +[Страница мануала Tmux](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/tmux.1?query=tmux) + +[Gentoo Wiki](http://wiki.gentoo.org/wiki/Tmux) + +[Archlinux Wiki](https://wiki.archlinux.org/index.php/Tmux) + +[Отображение CPU/MEM % в статусбаре](https://stackoverflow.com/questions/11558907/is-there-a-better-way-to-display-cpu-usage-in-tmux) diff --git a/ru-ru/typescript-ru.html.markdown b/ru-ru/typescript-ru.html.markdown new file mode 100644 index 00000000..67b58a38 --- /dev/null +++ b/ru-ru/typescript-ru.html.markdown @@ -0,0 +1,173 @@ +--- +language: TypeScript +lang: ru-ru +contributors: +    - ["Philippe Vlérick", "https://github.com/pvlerick"] +translators: +    - ["Fadil Mamedov", "https://github.com/fadilmamedov"] +    - "Andre Polykanine", "https://github.com/Oire"] +filename: learntypescript-ru.ts +--- + +TypeScript — это язык программирования, целью которого является лёгкая разработка широкомасштабируемых JavaScript-приложений. +TypeScript добавляет в Javascript общие концепции, такие, как классы, модули, интерфейсы, обобщённое программирование и (опционально) статическую типизацию.   +Это надмножество языка JavaScript: весь JavaScript-код является валидным TypeScript-кодом, следовательно, может быть добавлен бесшовно в любой проект.  +Компилятор TypeScript генерирует JavaScript-код. + +Эта статья концентрируется только на синтаксисе TypeScript, в противовес статье о [JavaScript](javascript-ru/). + +Для тестирования компилятора TypeScript пройдите по ссылке в [песочницу](http://www.typescriptlang.org/Playground).  +Там вы можете написать код (с поддержкой автодополнения) и сразу же увидеть сгенерированный JavaScript код. + +```js +// В TypeScript есть 3 базовых типа +var isDone: boolean = false; +var lines: number = 42; +var name: string = "Андерс"; + +// Тип «any» для случаев, когда заранее неизвестен тип переменной +var notSure: any = 4; +notSure = "а может быть, строка"; +notSure = false; // а теперь логический тип + +// Для коллекций есть типизированные массивы и обобщённые массивы +var list: number[] = [1, 2, 3]; +// Как альтернатива, использование обобщённого массива +var list: Array<number> = [1, 2, 3]; + +// Перечисления: +enum Color {Red, Green, Blue}; +var c: Color = Color.Green; + +// Наконец, «void» используется для обозначения того, что функция ничего не возвращает +function bigHorribleAlert(): void { +  alert("Я маленькое надоедливое окошко!"); +} + +// Функции — это объекты первого класса. Они поддерживают лямбда-синтаксис (=>) +// и используют вывод типов (type inference) + +// Следующие строки кода являются эквивалентными, компилятором предполагается +// одинаковая сигнатура, на выходе генерируется одинаковый JavaScript-код +var f1 = function(i: number): number { return i * i; } +// Предполагается возвращаемый тип +var f2 = function(i: number) { return i * i; } +var f3 = (i: number): number => { return i * i; } +// Предполагается возвращаемый тип +var f4 = (i: number) => { return i * i; } +// Предполагается возвращаемый тип, в однострочной функции ключевое слово «return» не нужно +var f5 = (i: number) =>  i * i; + +// Интерфейсы являются структурными; всё, что имеет свойства, совместимо с интерфейсом +interface Person { +  name: string; +  // Опциональные свойства, помеченные символом «?» +  age?: number; +  // И, конечно, функции +  move(): void; +} + +// Объект, который реализует интерфейс «Person» +// К нему можно обращаться, как к «Person», так как он имеет свойства «name» и «move» +var p: Person = { name: "Бобби", move: () => {} }; +// Объекты, которые могут иметь опциональные свойства: +var validPerson: Person = { name: "Бобби", age: 42, move: () => {} }; +// Это не «Person», поскольку «age» не является числовым значением +var invalidPerson: Person = { name: "Бобби", age: true }; + +// Интерфейсы могут также описывать функциональный тип +interface SearchFunc { +  (source: string, subString: string): boolean; +} +// Важны только типы параметров, имена — нет. +var mySearch: SearchFunc; +mySearch = function(src: string, sub: string) { +  return src.search(sub) != -1; +} + +// Классы. Члены класса по умолчанию являются публичными +class Point { +  	// Свойства +    x: number; + +    // Конструктор — ключевые слова public/private в данном контексте сгенерируют +    // шаблонный код для свойства и для инициализации в конструкторе +    // В данном примере «y» будет определён так же, как и «x», но меньшим количеством кода +    // Значения по умолчанию также поддерживаются + +    constructor(x: number, public y: number = 0) { +        this.x = x; +    } + +    // Функции +    dist() { return Math.sqrt(this.x * this.x + this.y * this.y); } + +    // Статические члены +    static origin = new Point(0, 0); +} + +var p1 = new Point(10 ,20); +var p2 = new Point(25); //y будет равен 0 + +// Наследование +class Point3D extends Point { +    constructor(x: number, y: number, public z: number = 0) { +        super(x, y); // Явный вызов конструктора базового класса обязателен +    } + +    // Перегрузка +    dist() { +        var d = super.dist(); +        return Math.sqrt(d * d + this.z * this.z); +    } +} + +// Модули, знак «.» может быть использован как разделитель для обозначения подмодулей +module Geometry { +  export class Square { +    constructor(public sideLength: number = 0) { +    } +    area() { +      return Math.pow(this.sideLength, 2); +    } +  } +} + +var s1 = new Geometry.Square(5); + +// Локальный псевдоним для ссылки на модуль +import G = Geometry; + +var s2 = new G.Square(10); + +// Обобщённое программирование +// Классы +class Tuple<T1, T2> { +    constructor(public item1: T1, public item2: T2) { +    } +} + +// Интерфейсы +interface Pair<T> { +    item1: T; +    item2: T; +} + +// И функции +var pairToTuple = function<T>(p: Pair<T>) { +    return new Tuple(p.item1, p.item2); +}; + +var tuple = pairToTuple({ item1:"hello", item2:"world"}); + +// Включение ссылки на файл определения: +/// <reference path="jquery.d.ts" /> + +``` + +## Для дальнейшего чтения + * [Официальный веб-сайт TypeScript](http://www.typescriptlang.org/) + * [Спецификация языка TypeScript (pdf)](http://go.microsoft.com/fwlink/?LinkId=267238) + * [Anders Hejlsberg — Introducing TypeScript на Channel 9](http://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript) + * [Исходный код на GitHub](https://github.com/Microsoft/TypeScript) + * [Definitely Typed — репозиторий определений типов](http://definitelytyped.org/) | 
