diff options
Diffstat (limited to 'ru-ru')
25 files changed, 3794 insertions, 252 deletions
| diff --git a/ru-ru/asymptotic-notation-ru.html.markdown b/ru-ru/asymptotic-notation-ru.html.markdown new file mode 100644 index 00000000..73ad80ba --- /dev/null +++ b/ru-ru/asymptotic-notation-ru.html.markdown @@ -0,0 +1,225 @@ +--- +category: Algorithms & Data Structures +name: Asymptotic Notation +contributors: +    - ["Jake Prather", "http://github.com/JakeHP"] +    - ["Divay Prakash", "http://github.com/divayprakash"] +translators: +    - ["pru-mike", "http://gihub.com/pru-mike"] +lang: ru-ru +--- + +# О-cимволика + +## Что это такое? + +О-cимволика или асимптотическая запись это система символов позволяющая оценить +время выполнения алгоритма, устанавливая зависимость времени выполнения от +увеличения объема входных данных, так же известна как оценка +сложности алгоритмов. Быстро-ли алгоритм станет невероятно медленным, когда +объем входных данных увеличится? Будет-ли алгоритм выполняться достаточно быстро, +если объем входных данных возрастет? О-символика позволяет ответить на эти +вопросы. + +## Можно-ли по-другому найти ответы на эти вопросы? + +Один способ это подсчитать число элементарных операций в зависимости от +различных объемов входных данных. Хотя это и приемлемое решение, тот объем +работы которого оно потребует, даже для простых алгоритмов, делает его  +использование неоправданным. + +Другой способ это измерить какое время алгоритм потребует для завершения на +различных объемах входных данных. В тоже время, точность и относительность +(полученное время будет относиться только к той машине на которой оно +вычислено) этого метода зависит от среды выполнения: компьютерного аппаратного +обеспечения, мощности процессора и т.д. + +## Виды О-символики + +В первом разделе этого документа мы определили, что О-символика +позволяет оценивать алгоритмы в зависимости от изменения размера входных +данных. Представим что алгоритм это функция f, n размер входных данных и  +f(n) время выполнения. Тогда для данного алгоритма f c размером входных +данных n получим какое-то результирующее время выполнения f(n). +Из этого можно построить график, где ось Y время выполнения, ось X размер входных +данных и точки на графике это время выполнения для заданного размера входных +данных. + +С помощью О-символики можно оценить функцию или алгоритм +несколькими различными способами. Например можно оценить алгоритм исходя +из нижней оценки, верхней оценки, тождественной оценки. Чаще всего встречается +анализ на основе верхней оценки. Как правило не используется нижняя оценка, +потому что она не подходит под планируемые условия. Отличный пример алгоритмы +сортировки, особенно добавление элементов в древовидную структуру. Нижняя оценка +большинства таких алгоритмов может быть дана как одна операция. В то время как в +большинстве случаев, добавляемые элементы должны быть отсортированы +соответствующим образом при помощи дерева, что может потребовать обхода целой +ветви. Это и есть худший случай, для которого планируется верхняя оценка. + +### Виды функций, пределы и упрощения + +``` +Логарифмическая функция - log n +Линейная функция - an + b +Квадратическая функция - an^2 + bn +c +Полиномиальная функция - an^z + . . . + an^2 + a*n^1 + a*n^0, где z константа +Экспоненциальная функция - a^n, где a константа +``` + +Приведены несколько базовых функций используемых при определении сложности в +различных оценках. Список начинается с самой медленно возрастающей функции +(логарифм, наиболее быстрое время выполнения) и следует до самой быстро +возрастающей функции (экспонента, самое медленное время выполнения). Отметим, +что в то время как 'n' или размер входных данных, возрастает в каждой из этих функций, +результат намного быстрее возрастает в квадратической, полиномиальной +и экспоненциальной по сравнению с логарифмической и линейной. + +Крайне важно понимать, что при использовании описанной далее нотации необходимо +использовать упрощенные выражения. +Это означает, что необходимо отбрасывать константы и слагаемые младших порядков, +потому что если размер входных данных (n в функции f(n) нашего примера) +увеличивается до бесконечности (в пределе), тогда слагаемые младших порядков +и константы становятся пренебрежительно малыми. Таким образом, если есть +константа например размера 2^9001 или любого другого невообразимого размера, +надо понимать, что её упрощение внесёт значительные искажения в точность +оценки. + +Т.к. нам нужны упрощенные выражения, немного скорректируем нашу таблицу... + +``` +Логарифм - log n +Линейная функция - n +Квадратическая функция - n^2 +Полиномиальная функция - n^z, где z константа +Экспонента - a^n, где a константа +``` + +### О-Большое +О-Большое, записывается как **О**, это асимптотическая запись для оценки худшего +случая или для ограничения заданой функции сверху. Это позволяет сделать  +_**асимптотическую оценку верхней границы**_ скорости роста времени выполнения  +алгоритма. Допустим `f(n)` время выполнения алгоритма и `g(n)` заданная временная +сложность которая проверяется для алгоритма. Тогда `f(n)` это O(g(n)), если +существуют действительные константы с (с > 0) и n<sub>0</sub>, такие +что `f(n)` <= `c g(n)` выполняется для всех n начиная с некоторого n<sub>0</sub> (n > n<sub>0</sub>). + +*Пример 1* + +``` +f(n) = 3log n + 100 +g(n) = log n +``` + +Является-ли `f(n)` O(g(n))? +Является-ли `3 log n + 100` O(log n)? +Посмотрим на определение О-Большого: + +``` +3log n + 100 <= c * log n +``` + +Существуют-ли константы c, n<sub>0</sub> такие что выражение верно для всех n > n<sub>0</sub> + +``` +3log n + 100 <= 150 * log n, n > 2 (неопределенно для n = 1) +``` + +Да! По определению О-Большого `f(n)` является O(g(n)). + +*Пример 2* + +``` +f(n) = 3 * n^2 +g(n) = n +``` + +Является-ли `f(n)` O(g(n))? +Является-ли `3 * n^2` O(n)? +Посмотрим на определение О-Большого: + +``` +3 * n^2 <= c * n +``` + +Существуют-ли константы c, n<sub>0</sub> такие что выражение верно для всех n > n<sub>0</sub>? +Нет, не существуют. `f(n)` НЕ ЯВЛЯЕТСЯ O(g(n)). + +### Омега-Большое +Омега-Большое, записывается как **Ω**, это асимптотическая запись для оценки +лучшего случая или для ограничения заданой функции снизу. Это позволяет сделать +_**асимптотическую оценку нижней границы**_ скорости роста времени выполнения  +алгоритма.  + +`f(n)` принадлежит Ω(g(n)), если существуют действительные константы +с (с > 0) и <sub>0</sub> (n<sub>0</sub> > 0), такие что `f(n)` >= `c g(n)` для всех n > n<sub>0</sub>. + +### Примечание + +Асимптотические оценки сделаные при помощи О-Большое и Омега-Большое могут +как быть так и не быть точными. Для того что бы обозначить что границы не +являются асимптотически точными используются записи о-малое и омега-малое. + +### О-Малое +O-Малое, записывается как **о**, это асимптотическая запись для оценки верхней +границы времени выполнения алгоритма, при условии что граница не является +асимптотически точной. + +`f(n)` является o(g(n)), если можно подобрать такие действительные константы, +что для всех c (c > 0) найдется n<sub>0</sub> (n<sub>0</sub> > 0), так +что `f(n)` < `c g(n)` выполняется для всех n (n > n<sub>0</sub>). + +Определения О-символики для О-Большое и О-Малое похожи. Главное отличие в том, +что если f(n) = O(g(n)), тогда условие f(n) <= c g(n) выполняется если _**существует**_ +константа c > 0, но если f(n) = o(g(n)), тогда условие f(n) < c g(n) выполняется +для _**всех**_ констант с > 0. + +### Омега-малое +Омега-малое, записывается как **ω**, это асимптотическая запись для оценки +верней границы времени выполнения алгоритма, при условии что граница не является +асимптотически точной. + +`f(n)` является ω(g(n)), если можно подобрать такие действительные константы, +что для всех c (c > 0) найдется n<sub>0</sub> (n<sub>0</sub> > 0), так +что `f(n)` > `c g(n)` выполняется для всех n (n > n<sub>0</sub>) + +Определения Ω-символики и ω-символики похожи. Главное отличие в том, что +если f(n) = Ω(g(n)), тогда условие f(n) >= c g(n) выполняется если _**существует**_ +константа c > 0, но если f(n) = ω(g(n)), тогда условие f(n) > c g(n) +выполняется для _**всех**_ констант с > 0. + +### Тета +Тета, записывается как **Θ**, это асимптотическая запись для оценки +_***асимптотически точной границы***_ времени выполнения алгоритма. + +`f(n)` является Θ(g(n)), если для некоторых действительных +констант c1, c2 и n<sub>0</sub> (c1 > 0, c2 > 0, n<sub>0</sub> > 0), +`c1 g(n)` < `f(n)` < `c2 g(n)` для всех n (n > n<sub>0</sub>). + +∴ `f(n)` является Θ(g(n)) означает что `f(n)` является O(g(n)) +и `f(n)` является Ω(g(n)). + +О-Большое основной инструмент для анализа сложности алгоритмов. +Так же смотрите примеры по ссылкам. + +### Заключение +Такую тему сложно изложить кратко, поэтому обязательно стоит пройти по ссылкам и +посмотреть дополнительную литературу. В них дается более глубокое описание с +определениями и примерами. + + +## Дополнительная литература + +* [Алгоритмы на Java](https://www.ozon.ru/context/detail/id/18319699/) +* [Алгоритмы. Построение и анализ](https://www.ozon.ru/context/detail/id/33769775/) + +## Ссылки + +* [Оценки времени исполнения. Cимвол O()](http://algolist.manual.ru/misc/o_n.php) +* [Асимптотический анализ и теория вероятностей](https://www.lektorium.tv/course/22903) + +## Ссылки (Eng) + +* [Algorithms, Part I](https://www.coursera.org/learn/algorithms-part1) +* [Cheatsheet 1](http://web.mit.edu/broder/Public/asymptotics-cheatsheet.pdf) +* [Cheatsheet 2](http://bigocheatsheet.com/) + 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/binary-search-ru.html.markdown b/ru-ru/binary-search-ru.html.markdown new file mode 100644 index 00000000..9ed62cb8 --- /dev/null +++ b/ru-ru/binary-search-ru.html.markdown @@ -0,0 +1,64 @@ +--- +category: Algorithms & Data Structures +name: Binary Search +contributors: +    - ["Abhishek Jaisingh", "http://github.com/abhishekjiitr"] +translators: +    - ["Evan K.", "https://github.com/justblah"] +lang: ru-ru     +--- + +# Двоичный (бинарный) поиск + +## Зачем использовать двоичный поиск? + +Поиск является одной из главных проблем в области вычислительной техники. На сегодняшний день осуществляется более одного триллиона поисковых запросов в год, поэтому нам нужны алгоритмы, которые могут делать это очень быстро. Двоичный поиск является одним из фундаментальных алгоритмов в информатике. Для его изучения мы освоим теорию, а затем используем её для реализации алгоритма. + +## Вступление + +Самый простой вариант поиска – линейный поиск, но этот подход занимает много времени, и растет линейно, пропорционально набору данных. Пример реализации – начинаем с крайнего левого элемента массива S, один за другим сравниваем искомое значение X с каждым элементом массива S, если X совпадает с элементом S, возвращаем индекс. Если X не совпадает ни с одним из элементов массива S, возвращаем -1. + +``` +Линейный поиск: O (n)            Линейная сложность + +Двоичный поиск: O ( log(n) )		 Логарифмическая сложность + +``` +``` +def search(arr, x): + +    for i in range(len(arr)): + +        if arr[i] == x: +            return i + +    return -1 + +``` + +## Алгоритм двоичного поиска + +Для корректной работы двоичного поиска набор данных для поиска должен быть отсортирован (в любом порядке). + +### Алгоритм + +``` +Главная идея двоичного поиска заключается в использовании информации о том, что массив уже отсортирован, +что и позволяет упростить сложность алгоритма до O(Logn). Мы попросту отбрасываем половину элементов набора сразу после одного сравнения. +1) Сравнить X с элементом в середине набора S. +2) Если X равен элементу в середине - возвращаем индекс среднего элемента. +3) Если значение X больше, чем средний элемент набора, значит X находится в правой части набора. Повторяем алгоритм для правой половины набора. +4) В противном случае (X меньше) повторяем алгоритм для левой половины набора. +Это и есть рекурсивная реализация двоичного поиска. + +``` + +### На заметку + +Существует и другая форма двоичного поиска, которая можеть быть полезна. + +## На почитать + +* [Проектирование, реализация и примеры](https://ru.wikipedia.org/wiki/%D0%94%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA) +* [Описание алгоритма ИТМО](http://neerc.ifmo.ru/wiki/index.php?title=%D0%A6%D0%B5%D0%BB%D0%BE%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA) +* [Ошибки при реализации бинарного поиска](https://habrahabr.ru/post/146228/) diff --git a/ru-ru/c++-ru.html.markdown b/ru-ru/c++-ru.html.markdown new file mode 100644 index 00000000..cef5ab7e --- /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() +{ +    std::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/c-ru.html.markdown b/ru-ru/c-ru.html.markdown index 5988b159..71e41ee3 100644 --- a/ru-ru/c-ru.html.markdown +++ b/ru-ru/c-ru.html.markdown @@ -11,7 +11,7 @@ lang: ru-ru  Что ж, Си всё ещё является лидером среди современных высокопроизводительных языков. -Для большинствоа программистов, Си – это самый низкоуровневый язык на котором они когда-либо писали, +Для большинства программистов, Си – это самый низкоуровневый язык на котором они когда-либо писали,  но этот язык даёт больше, чем просто повышение производительности.  Держите это руководство в памяти и вы сможете использовать Си максимально эффективно. @@ -145,7 +145,7 @@ int main() {      f1 / f2; // => 0.5, плюс-минус погрешность потому что,      // цифры с плавающей точкой вычисляются неточно! -    // Модуль +    // Остаток от деления      11 % 3; // => 2      // Операции сравнения вам уже знакомы, но в Си нет булевого типа. @@ -170,7 +170,7 @@ int main() {      !0; // => 1      1 && 1; // => 1 (логическое И)      0 && 1; // => 0 -    0 || 1; // => 1 (лигическое ИЛИ) +    0 || 1; // => 1 (логическое ИЛИ)      0 || 0; // => 0      // Битовые операторы @@ -202,7 +202,7 @@ int main() {      int ii = 0;      while (ii < 10) {          printf("%d, ", ii++); // инкрементация происходит после того как -                              // знаечние ii передано ("postincrement") +                              // значение ii передано ("postincrement")      } // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "      printf("\n"); @@ -212,7 +212,7 @@ int main() {      do {          printf("%d, ", kk);      } while (++kk < 10); // инкрементация происходит перед тем как -                         // передаётся знаечние kk ("preincrement") +                         // передаётся значение kk ("preincrement")      // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "      printf("\n"); @@ -229,7 +229,7 @@ int main() {      switch (some_integral_expression) {      case 0: // значения должны быть целыми константами (и могут быть выражениями)          do_stuff(); -        break; // если не написать break; то управление будет передено следующему блоку +        break; // если не написать break; то управление будет передано следующему блоку      case 1:          do_something_else();          break; @@ -247,7 +247,7 @@ int main() {      // Каждое выражение в Си имеет тип, но вы можете привести один тип к другому,       // если хотите (с некоторыми искажениями). -    int x_hex = 0x01; // Вы можете назначать переменные с помощью шеснадцатеричного кода. +    int x_hex = 0x01; // Вы можете назначать переменные с помощью шестнадцатеричного кода.      // Приведение типов будет пытаться сохранять цифровые значения.      printf("%d\n", x_hex); // => Prints 1 @@ -285,17 +285,17 @@ int main() {      printf("%zu, %zu\n", sizeof(px), sizeof(not_a_pointer));      // => Напечатает "8, 4" в 64 битной системе -    // Для того, чтобы получить знаечние по адресу, напечатайте * перед именем. -    // Да, использование * при объявлении указателя и получении значения по адресу +    // Для того, чтобы получить значение по адресу, напечатайте * перед именем. +    // Да, * используется при объявлении указателя и для получении значения по адресу      // немного запутано, но вы привыкнете. -    printf("%d\n", *px); // => Напечаатет 0, значение перемененной x +    printf("%d\n", *px); // => Напечатает 0, значение перемененной x      // Вы также можете изменять значение, на которое указывает указатель.      (*px)++; // Инкрементирует значение на которое указывает px на единицу      printf("%d\n", *px); // => Напечатает 1      printf("%d\n", x); // => Напечатает 1 -    // Массивы удобно использовать для болшого количества однотипных данных. +    // Массивы удобно использовать для большого количества однотипных данных.      int x_array[20];      int xx;      for (xx = 0; xx < 20; xx++) { @@ -305,9 +305,10 @@ int main() {      // Объявление указателя на int с адресом массива.      int* x_ptr = x_array;      // x_ptr сейчас указывает на первый элемент массива (со значением 20).  -    // Это рабоатет, потому что имя массива возвращает указатель на первый элемент. -    // Например, когда массив передаётся в функцию или назначается указателю, он -    // невявно преобразуется в указатель. +    // Это работает, потому что при обращении к имени массива возвращается  +    // указатель на первый элемент. +    // Например, когда массив передаётся в функцию или присваивается указателю, он +    // неяввно преобразуется в указатель.      // Исключения: когда массив является аргументом для оператор '&':      int arr[10];      int (*ptr_to_arr)[10] = &arr; // &arr не является 'int *'! @@ -422,7 +423,7 @@ void function_1() {      // Вы можете объявить указатель на структуру      struct rectangle *my_rec_ptr = &my_rec; -    // Можно доступаться к структуре и через указатель +    // Можно получить доступ к структуре и через указатель      (*my_rec_ptr).width = 30;      // ... или ещё лучше: используйте оператор -> для лучшей читабельночти @@ -436,7 +437,7 @@ int area(rect r) {      return r.width * r.height;  } -// Если вы имеете большую структуру, можно доступаться к ней "по указателю", +// Если вы имеете большую структуру, можно получить доступ к ней "по указателю",  // чтобы избежать копирования всей структуры.  int area(const rect *r) {      return r->width * r->height; @@ -456,7 +457,7 @@ int area(const rect *r) {  void str_reverse_through_pointer(char *str_in) {      // Определение функции через указатель. -    void (*f)(char *); // Сигнатура должна полность совпадать с целевой функцией. +    void (*f)(char *); // Сигнатура должна полностью совпадать с целевой функцией.      f = &str_reverse; // Присвоить фактический адрес (во время исполнения)      // "f = str_reverse;" тоже будет работать.      //Имя функции (как и массива) возвращает указатель на начало. diff --git a/ru-ru/clojure-ru.html.markdown b/ru-ru/clojure-ru.html.markdown index 451da312..356d1cc0 100644 --- a/ru-ru/clojure-ru.html.markdown +++ b/ru-ru/clojure-ru.html.markdown @@ -321,7 +321,7 @@ keymap ; => {:a 1, :b 2, :c 3} - оригинал не был затронут  ; Также модуль может быть импортирован формой require  (require 'clojure.string) -; После этого модуль становится доступе в текущем пространстве имен, +; После этого модуль становится доступен в текущем пространстве имен,  ; а вызов его функций может быть осуществлен указанием полного имени функции:  (clojure.string/blank? "") ; => true diff --git a/ru-ru/css-ru.html.markdown b/ru-ru/css-ru.html.markdown index 2e2d40b7..e0e5e30b 100644 --- a/ru-ru/css-ru.html.markdown +++ b/ru-ru/css-ru.html.markdown @@ -116,7 +116,7 @@ element:visited {}  /* или еще не проходил по ней */  element:link {} -/* выбранное поле воода (input) */ +/* выбранное поле ввода (input) */  element:focus {} @@ -132,7 +132,7 @@ selector {      width: 200px; /* пиксели */      font-size: 20pt; /* пункты */      width: 5cm; /* сантиметры */ -    min-width: 50mm; /* милиметры */ +    min-width: 50mm; /* миллиметры */      max-width: 5in; /* дюймы */      height: 0.2vh; /* умножается на высоту окна браузера (CSS3) */      width: 0.4vw; /* умножается на ширину окна браузера (CSS3) */ @@ -235,7 +235,7 @@ p { property: value !important; }  ## Совместимость -Несмотря на то, что большая часть функций CSS2 (а также CSS3) подеррживается всеми +Несмотря на то, что большая часть функций CSS2 (а также CSS3) поддерживается всеми  браузерами и устройствами, не забывайте проверять совместимость CSS-правил  с современными браузерами. diff --git a/ru-ru/d-ru.html.markdown b/ru-ru/d-ru.html.markdown index 8f4233fd..bfa3f085 100644 --- a/ru-ru/d-ru.html.markdown +++ b/ru-ru/d-ru.html.markdown @@ -1,5 +1,5 @@  --- -language: d +language: D  filename: learnd-ru.d  contributors:      - ["Anton Pastukhov", "http://dprogramming.ru/"] @@ -7,11 +7,12 @@ contributors:      - ["Andre Polykanine", "http://oire.me/"]  lang: ru-ru  --- +  D - современный компилируемый язык общего назначения с Си-подобным синтаксисом,  который сочетает удобство, продуманный дизайн и высокую производительность.  D - это С++, сделанный правильно. -```d +```c  // Welcome to D! Это однострочный комментарий  /* многострочный diff --git a/ru-ru/forth-ru.html.markdown b/ru-ru/forth-ru.html.markdown new file mode 100644 index 00000000..05316578 --- /dev/null +++ b/ru-ru/forth-ru.html.markdown @@ -0,0 +1,240 @@ +--- +language: forth +contributors: +    - ["Horse M.D.", "http://github.com/HorseMD/"] +translators: +    - ["Dmitrii Kuznetsov", "https://github.com/torgeek"] +filename: learnforth-ru.fs +lang: ru-ru +--- + +Форт создан Чарлзом Муром в 70-е годы. Это императивный, стековый язык программирования и среда исполнения программ. Использовался в таких проектах как Open Firmware. Продолжает применятся в проектах. Применяется в НАСА. + +Внимание: эта материал использует реализацию Форта - Gforth, но большая часть написанного будет работать в других средах. + +``` +\ Это комментарий +( Это тоже комментарий, но использыется для предоределённых слов ) + +\ --------------------------------- Прекурсор -------------------------------- + +\ Всё программирование на Форте заключается в манипулировании  +\ параметрами на стеке. +5 2 3 56 76 23 65    \ ok + +\ Эти числа добавляются в стек слева направо +.s    \ <7> 5 2 3 56 76 23 65 ok + +\ В Форте всё - это слова-команды или числа. Слова разделяются любым числом +\ пробелов и переходов на новую строку. Длина слова не больше 31 литеры. + +\ ---------------------------- Базовая арифметика ---------------------------- + +\ Арифметика (фактически все ключевые слова требуют данных) - это манипуляция  +\ данными на стеке. +5 4 +    \ ok + +\ `.` показывает верхнее значение в стеке: +.    \ 9 ok + +\ Ещё примеры арифметических выражений: +6 7 * .        \ 42 ok +1360 23 - .    \ 1337 ok +12 12 / .      \ 1 ok +13 2 mod .     \ 1 ok + +99 negate .    \ -99 ok +-99 abs .      \ 99 ok +52 23 max .    \ 52 ok +52 23 min .    \ 23 ok + +\ --------------------------- Манипуляции со стеком --------------------------- + +\ Естественно, когда мы работаем со стеком, то используем  +\ больше полезных методов: + +3 dup -          \ дублировать верхний элемент в стеке  +                 \ (1-й становится эквивалентным 2-му): 3 - 3 +2 5 swap /       \ поменять местами верхний элемент со 2-м элементом: 5 / 2 +6 4 5 rot .s     \ сменять по очереди 3-и верхних элемента: 4 5 6 +4 0 drop 2 /     \ снять верхний элемент (не печатается на экране): 4 / 2 +1 2 3 nip .s     \ снять второй элемент (подобно исключению элемента):   1 3 + +\ ------------------ Более продвинутые манипуляции со стеком ------------------ + +1 2 3 4 tuck   \ дублировать верхний елемент стека во вторую позицию:  +               \ 1 2 4 3 4 ok +1 2 3 4 over   \ диблировать второй елемент наверх стека:  +               \ 1 2 3 4 3 ok +1 2 3 4 2 roll \ *переместить* элемент в заданной позиции наверх стека: +               \ 1 3 4 2 ok +1 2 3 4 2 pick \ *дублировать* элемент в заданной позиции наверх:  +               \ 1 2 3 4 2 ok + +\ Внимание! Обращения к стеку индексируются с нуля. + +\ --------------------------- Создание новых слов ----------------------------- + +\ Определение новых слов через уже известные. Двоеточие `:` переводит Форт  +\ в режим компиляции выражения, которое заканчивается точкой с запятой `;`. +: square ( n -- n ) dup * ;    \ ok +5 square .                     \ 25 ok + +\ Мы всегда можем посмотреть, что содержится в слове: +see square     \ : square dup * ; ok + +\ -------------------------------- Зависимости -------------------------------- + +\ -1 == true, 0 == false. Однако, некоторые ненулевые значения  +\ обрабатываются как true: +42 42 =    \ -1 ok +12 53 =    \ 0 ok + +\ `if` это компилируемое слово. `if` <stuff to do> `then` <rest of program>. +: ?>64 ( n -- n ) dup 64 > if ." Больше чем 64!" then ;    +\ ok +100 ?>64                                                   +\ Больше чем 64! ok + +\ Else: +: ?>64 ( n -- n ) dup 64 > if ." Больше чем 64!" else ." меньше чем 64!" then ; +100 ?>64    \ Больше чем 64! ok +20 ?>64     \ меньше чем 64! ok + +\ ------------------------------------ Циклы ----------------------------------- + +\ `do` это тоже компилируемое слово. +: myloop ( -- ) 5 0 do cr ." Hello!" loop ; \ ok +myloop +\ Hello! +\ Hello! +\ Hello! +\ Hello! +\ Hello! ok + +\ `do` предполагает наличие двух чисел на стеке: конечное и начальное число. + +\ Мы можем назначить в цикле переменную `i` для значения индекса: +: one-to-12 ( -- ) 12 0 do i . loop ;     \ ok +one-to-12                                 \ 0 1 2 3 4 5 6 7 8 9 10 11 12 ok + +\ `?do` работает подобным образом, за исключением пропуска начального  +\ и конечного значения индекса цикла. +: squares ( n -- ) 0 ?do i square . loop ;   \ ok +10 squares                                   \ 0 1 4 9 16 25 36 49 64 81 ok + +\ Изменение "шага" цикла проиводится командой `+loop`: +: threes ( n n -- ) ?do i . 3 +loop ;    \ ok +15 0 threes                             \ 0 3 6 9 12 ok + +\ Запуск бесконечного цикла - `begin` <stuff to do> <flag> `until`: +: death ( -- ) begin ." Вы всё ещё здесь?" 0 until ;    \ ok + +\ ---------------------------- Переменные и память ---------------------------- + +\ Используйте `variable`, что бы объявить `age` в качестве переменной. +variable age    \ ok + +\ Затем мы запишем число 21 в переменную 'age' (возраст) словом `!`. +21 age !    \ ok + +\ В заключении мы можем напечатать значение переменной прочитав его словом `@`,  +\ которое добавит значение на стек или использовать слово `?`,  +\ что бы прочитать и распечатать в одно действие. +age @ .    \ 21 ok +age ?      \ 21 ok + +\ Константы объявляются аналогично, за исключем того, что мы не должны  +\ беспокоиться о выделении адреса в памяти: +100 constant WATER-BOILING-POINT    \ ok +WATER-BOILING-POINT .               \ 100 ok + +\ ---------------------------------- Массивы ---------------------------------- + +\ Создание массива похоже на объявление переменной, но нам нужно выделить +\ больше памяти. + +\ Вы можете использовать слова `2 cells allot` для создания массива  +\ размером 3 элемента: +variable mynumbers 2 cells allot    \ ok + +\ Инициализировать все значения в 0 +mynumbers 3 cells erase    \ ok + +\ В качестве альтернативы мы можем использовать `fill`: +mynumbers 3 cells 0 fill + +\ или мы можем пропустить все слова выше и инициализировать массив  +\ нужными значениями: +create mynumbers 64 , 9001 , 1337 , \ ok (the last `,` is important!) + +\ ... что эквивалентно: + +\ Ручная запись значений по индексам ячеек: +64 mynumbers 0 cells + !      \ ok +9001 mynumbers 1 cells + !    \ ok +1337 mynumbers 2 cells + !    \ ok + +\ Чтение значений по индексу: +0 cells mynumbers + ?    \ 64 ok +1 cells mynumbers + ?    \ 9001 ok + +\ Мы можем просто сделать собственное слово для манипуляции массивом: +: of-arr ( n n -- n ) cells + ;    \ ok +mynumbers 2 of-arr ?               \ 1337 ok + +\ Которую тоже можно использовать для записи значений: +20 mynumbers 1 of-arr !    \ ok +mynumbers 1 of-arr ?       \ 20 ok + +\ ------------------------------ Стек возвратов ------------------------------ + +\ Стек возвратов используется для удержания ссылки, +\ когда одно слово запускает другое, например, в цикле. + +\ Мы всегда видим это, когда используем `i`, которая возвращает дубль верхнего +\ значения стека. `i` это эквивалент `r@`. +: myloop ( -- ) 5 0 do r@ . loop ;    \ ok + +\ Так же как при чтении мы можем добавить ссылку в стек возвратов и удалить её: +5 6 4 >r swap r> .s    \ 6 5 4 ok + +\ Внимание: так как Форт использует стек возвратов для указателей на слово `>r` +\ следует всегда пользоваться `r>`. + +\ ---------------- Операции над числами с плавающей точкой -------------------- + +\ Многие фортовцы стараются избегать использование слов с вещественными числами. +8.3e 0.8e f+ f.    \ 9.1 ok + +\ Обычно мы просто используем слово 'f', когда обращаемся к вещественным числам: +variable myfloatingvar    \ ok +4.4e myfloatingvar f!     \ ok +myfloatingvar f@ f.       \ 4.4 ok + +\ ---------- В завершение несколько полезных замечаний и слов ----------------- + +\ Указание несуществующего слова очистит стек. Тем не менее, есть специальное  +\ слово для этого: +clearstack + +\ Очистка экрана: +page + +\ Загрузка форт-файла: +\ s" forthfile.fs" included + +\ Вы можете вывести список всех слов словаря Форта (это большой список!): +words + +\ Выход из Gforth: +bye + +``` + +##Готовы к большему? + +* [Начала Форта (англ.)](http://www.forth.com/starting-forth/) +* [Простой Форт (англ.)](http://www.murphywong.net/hello/simple.htm) +* [Мышление Форта (англ.)](http://thinking-forth.sourceforge.net/) +* [Учебники Форта (рус.)](http://wiki.forth.org.ru/УчебникиФорта) diff --git a/ru-ru/go-ru.html.markdown b/ru-ru/go-ru.html.markdown index e06ae9bd..6c8622cc 100644 --- a/ru-ru/go-ru.html.markdown +++ b/ru-ru/go-ru.html.markdown @@ -35,6 +35,7 @@ package main  // Import предназначен для указания зависимостей этого файла.  import (      "fmt"      // Пакет в стандартной библиотеке Go +    "io/ioutil" // Реализация функций ввод/ввывода.      "net/http" // Да, это веб-сервер!      "strconv"  // Конвертирование типов в строки и обратно      m "math"   // Импортировать math под локальным именем m. @@ -321,6 +322,14 @@ func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {      // Обработка запроса и отправка данных методом из http.ResponseWriter      w.Write([]byte("You learned Go in Y minutes!"))  } + +func requestServer() { +    resp, err := http.Get("http://localhost:8080") +    fmt.Println(err) +    defer resp.Body.Close() +    body, err := ioutil.ReadAll(resp.Body) +    fmt.Printf("\nWebserver said: `%s`", string(body)) +}  ```  ## Что дальше diff --git a/ru-ru/haskell-ru.html.markdown b/ru-ru/haskell-ru.html.markdown index e15fe6b7..fecee51b 100644 --- a/ru-ru/haskell-ru.html.markdown +++ b/ru-ru/haskell-ru.html.markdown @@ -66,7 +66,7 @@ not False -- True  ---------------------------------------------------- --- Списки и Кортежи +-- 2. Списки и Кортежи  ----------------------------------------------------  -- Все элементы списка в Haskell diff --git a/ru-ru/html-ru.html.markdown b/ru-ru/html-ru.html.markdown new file mode 100644 index 00000000..5069d77f --- /dev/null +++ b/ru-ru/html-ru.html.markdown @@ -0,0 +1,129 @@ +--- +language: html +filename: learnhtml.html +contributors: +    - ["Christophe THOMAS", "https://github.com/WinChris"] +translators: +    - ["Lana Tim", "https://github.com/LanaTim"] +lang: ru-ru +--- + +HTML расшифровывается как Hypertext Markup Language(гипертекстовый язык разметки). +Это язык используют для написания страниц для World Wide Web(всемирной паутины). +Это язык разметки позволяет писать веб-страниц с помощью кода, чтобы определять,  +как должны быть отображены текст и данные. +На самом деле, HTML файлы представляют собой простые текстовые файлы. +Что такое разметка? Это способ организации данных страницы, +путем открытия и закрытия тегов(помещая данные внутрь этих тегов). +Эта разметка служит, чтобы придать значение тексту, который он окружает. +Как и в других языках программирования, HTML имеет много версий. Здесь мы будем говорить о HTML5. + + +**Примечание:** Вы можете тестировать различные теги и элементы по мере продвижения  +через учебник на сайте, как [codepen](http://codepen.io/pen/) для того, чтобы увидеть  +их влияние, понять, как они работают и ознакомиться с языком. +В данной статье рассматривается в основном HTML синтаксис и некоторые полезные советы. + +```html +<!-- Комментарии заключаются как эта лини\! --> + +<!-- #################### Теги #################### --> +    +<!-- Ниже приведен пример HTML-файл, который мы будем анализировать. --> + +<!doctype html> +	<html> +		<head> +			<title>Мой сайт</title> +		</head> +		<body> +			<h1>Привет, мир!</h1> +			<a href = "http://codepen.io/anon/pen/xwjLbZ"> +				Переходите сюда, чтоб посмотреть как это выглядит. +			</a> +			<p>Это параграф.</p> +			<p>Это другой параграф.</p> +			<ul> +				<li>Это элемент не нумерованного списка (маркированный список)</li> +				<li>Это другой элемент</li> +				<li>Это последний элемент в списке</li> +			</ul> +		</body> +	</html> + +<!-- HTML-файл всегда начинается с указанием браузеру, что страница это HTML. --> +<!doctype html> + +<!-- После этого, страница начинается с <html> тега. --> +<html> + +<!-- страница будет закрыта в конце с помощью тега </html>. --> +</html> + +<!-- Ничто не должно появиться после этого заключительного тега. --> + +<!-- Внутри (между открывающим и закрывающим тегами <html> </ html>), мы находим: --> + +<!-- Заголовок определяется <head> (it он должен быть закрыт </head>). --> +<!-- Заголовок содержит описание и дополнительную информацию, которая не отображается; это метаданные. --> + +<head> +	<title>Мой сайт</title><!-- Тег <title> указывает браузеру заголовок, чтобы показать в строке заголовка названия и вкладки браузера окна. --> +</head> + +<!-- После секция <head>, находится секция - <body> --> +<!-- До этого момента, ничего описаное не будет отображаться в окне браузера. --> +<!-- Мы должны наполнить <body>  содержанием, которое будет отображаться. --> + +<body> +	<h1>Hello, world!</h1> <!-- Тег h1 создает заголовок. --> +	<!-- Так же существуют другие заголовки от имеющего большее значение <h1> по убыванию к  <h6>. --> +	<a href = "http://codepen.io/anon/pen/xwjLbZ">Переходите сюда, чтоб посмотреть как это выглядит.</a> +	<!--гиперссылка на URL, заданнf атрибутом href="" --> +	<p>Это параграф.</p> <!-- Тег <p> позволяет нам добавдять текст на странице HTML. --> +	<p>Это другой параграф.</p> +	<ul> <!-- Тег <ul> создает маркированный список. --> +	<!-- Для того, чтобы иметь пронумерованный список лучше использовать <ol>  +		тогда первый элемент будет иметь значение 1. для второго элемента, 2. и так далее. --> +		<li>Это элемент в не нумерованном списке (маркированный список)</li> +		<li>Это еще один элемент</li> +		<li>И это последний пункт в списке</li> +	</ul> +</body> + +<!-- Вот так просто можно создать HTML страницу. --> + +<!--Но можно добавить множество дополнительных типов HTML тегов. --> + +<!-- Для вставки картинки --> +<img src="http://i.imgur.com/XWG0O.gif"/> <!-- Источник изображения указывается с помощью атрибута src="" --> +<!-- Источником может быть URL или даже путь к файлу на вашем компьютере. --> + +<!-- Кроме того, можно создать таблицу. --> + +<table> <!-- Мы открыли <table> элемент. --> +	<tr> <!-- <tr> позволяет создать ряд. --> +		<th>Первый заголовок</th> <!-- <th> позволяет дать название для столбца таблицы. --> +		<th>Второй заголовок</th> +	</tr> +	<tr> +		<td>Первый ряд, первая колонка</td> <!-- <td> позволяет нам создать ячейку таблицы. --> +		<td>Первый ряд, вторая колонка</td> +	</tr> +	<tr> +		<td>Второй ряв, первая колонка</td> +		<td>Второй ряд, вторая колонка</td> +	</tr> +</table> + +``` + +## Применение + +HTML файлы имеют окончание(расширение) `.html`. + +## Узнать больше + +* [википедиа](https://ru.wikipedia.org/wiki/HTML) +* [HTML учебник](https://developer.mozilla.org/ru/docs/Web/HTML) +* [htmlbook](http://htmlbook.ru/) 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/javascript-ru.html.markdown b/ru-ru/javascript-ru.html.markdown index 54499f46..1f1ffce6 100644 --- a/ru-ru/javascript-ru.html.markdown +++ b/ru-ru/javascript-ru.html.markdown @@ -359,6 +359,7 @@ myFunc(); // = undefined  // И наоборот, функция может быть присвоена объекту и получать доступ к нему  // через this, даже если она не была прикреплена к нему при объявлении.  var myOtherFunc = function() { +    return this.myString.toUpperCase();  }  myObj.myOtherFunc = myOtherFunc;  myObj.myOtherFunc(); // = "ПРИВЕТ, МИР!" diff --git a/ru-ru/kotlin-ru.html.markdown b/ru-ru/kotlin-ru.html.markdown new file mode 100644 index 00000000..21940e41 --- /dev/null +++ b/ru-ru/kotlin-ru.html.markdown @@ -0,0 +1,375 @@ +--- +language: kotlin +filename: LearnKotlin-ru.kt +lang: ru-ru +contributors: +    - ["S Webber", "https://github.com/s-webber"] +translators: +    - ["Vadim Toptunov", "https://github.com/VadimToptunov"] +--- + +Kotlin - статистически типизированный язык для JVM, Android и браузера. Язык полностью cjdvtcnbv c Java.  +[Более детальная информация здесь.](https://kotlinlang.org/) + +```kotlin +// Однострочные комментарии начинаются с // +/* +А вот так выглядят многострочные комментарии. +*/ + +// Ключевое слово "package" действует и используется // абсолютно также, как и в Java. +package com.learnxinyminutes.kotlin + +/* +Точкой входа в программу на языке Kotlin является функция "main". +Приведенная ниже функция передает массив, содержащий любые аргументы из командной строки. +*/ +fun main(args: Array<String>) { +    /* +    Объявление значений производится с помощью или "var", или "val". +    Значения объявленные с помощью "val" не могут быть изменены или перезаписаны, в то время как объявленные с помощью "var" - могут. +    */ +    val fooVal = 10 // мы не можем потом изменить значение fooVal на какое-либо иное +    var fooVar = 10 +    fooVar = 20 // значение fooVar затем может быть изменено. + +    /* +    В большинстве случаев Kotlin самостоятельно может определить тип переменной, поэтому нам не нужно явно указывать его каждый раз. +    Мы можем явно объявить тип переменной следующим образом: +    */ +    val foo: Int = 7 + +    /* +    Строки могут быть представлены тем же образом, что и в Java. +    Для экранирования используется обратный слэш. +    */ +    val fooString = "My String Is Here!" +    val barString = "Printing on a new line?\nNo Problem!" +    val bazString = "Do you want to add a tab?\tNo Problem!" +    println(fooString) +    println(barString) +    println(bazString) + +    /* +    Необработанная строка разделяется тройной кавычкой ("""). +    Необработанные строки могут содержать символы новой строки и любые другие символы. +    */ +    val fooRawString = """ +fun helloWorld(val name : String) { +   println("Hello, world!") +} +""" +    println(fooRawString) + +    /* +    Строки могут содержать в себе шаблонные выражения. +    Шаблонные выражения начинаются со знака доллара ($). +    */ +    val fooTemplateString = "$fooString has ${fooString.length} characters" +    println(fooTemplateString) + +    /* +    Переменная, которая содержит null должна быть явно обозначена как nullable. +    Переменная может быть обозначена как nullable с помощью добавления знака вопроса(?) к ее типу. +    Мы можем получить доступ к nullable переменной используя оператор ?. . +    Для того, чтобы указать иное значение, если переменная является null, мы используем оператор ?: . +    */ +    var fooNullable: String? = "abc" +    println(fooNullable?.length) // => 3 +    println(fooNullable?.length ?: -1) // => 3 +    fooNullable = null +    println(fooNullable?.length) // => null +    println(fooNullable?.length ?: -1) // => -1 + +    /* +    Функции могут быть объявлены с помощью ключевого слова "fun". +    Аргументы функции указываются в скобках после имени функции. +    Аргументы функции также могу иметь и значение по умолчанию. +    Если требуется, то тип возвращаемого функцией значения, может быть указан после аргументов. +    */ +    fun hello(name: String = "world"): String { +        return "Hello, $name!" +    } +    println(hello("foo")) // => Hello, foo! +    println(hello(name = "bar")) // => Hello, bar! +    println(hello()) // => Hello, world! + +    /* +    Параметр функции может быть отмечен с помощью ключевого слова "vararg", для того чтобы позволить аргументам попасть в функцию. +    */ +    fun varargExample(vararg names: Int) { +        println("Argument has ${names.size} elements") +    } +    varargExample() // => Argument has 0 elements +    varargExample(1) // => Argument has 1 elements +    varargExample(1, 2, 3) // => Argument has 3 elements + +    /* +    Если функция состоит из одиночного выражения, фигурные скобки могут быть опущены. Тело функции указывается после знака = . +    */ +    fun odd(x: Int): Boolean = x % 2 == 1 +    println(odd(6)) // => false +    println(odd(7)) // => true + +    // Если возвращаемый тип может быть выведен, то нам не нужно его дополнительно указывать. +    fun even(x: Int) = x % 2 == 0 +    println(even(6)) // => true +    println(even(7)) // => false + +    // Функции могут брать другие функции в качестве аргументов, а также могут возвращать функции.  +    fun not(f: (Int) -> Boolean): (Int) -> Boolean { +        return {n -> !f.invoke(n)} +    } +    // Именованные функции могут быть определены в качестве аргументов с помощью оператора :: . +    val notOdd = not(::odd) +    val notEven = not(::even) +    // Lambda-выражения могут быть определены в качестве аргументов. +    val notZero = not {n -> n == 0} +    /* +    Если lambda-выражение имеет только один параметр, то ее определение может быть опущено (вместе с ->). +    Имя этого единственного параметра будет "it". +    */ +    val notPositive = not {it > 0} +    for (i in 0..4) { +        println("${notOdd(i)} ${notEven(i)} ${notZero(i)} ${notPositive(i)}") +    } + +    // Ключевое слово "class" используется для  +    // объявления классов. +    class ExampleClass(val x: Int) { +        fun memberFunction(y: Int): Int { +            return x + y +        } + +        infix fun infixMemberFunction(y: Int): Int { +            return x * y +        } +    } +    /* +    Чтобы создать новый экземпляр класса, нужно вызвать конструктор. +    Обратите внимание, что в Kotlin нет ключевого слова "new". +    */ +    val fooExampleClass = ExampleClass(7) +    // Функции-члены могут быть вызваны с использованием точечной нотации. +    println(fooExampleClass.memberFunction(4)) // => 11 +    /* +    В случае, если функция была помечена ключевым словом "infix", она может быть вызвана с помощью инфиксной нотации.  +    */ +    println(fooExampleClass infixMemberFunction 4) // => 28 + +    /* +    Data-классы - это компактный способ создать классы, которые лишь хранят данные. +    Методы "hashCode"/"equals" и "toString" генерируютсяч автоматически.  +    */ +    data class DataClassExample (val x: Int, val y: Int, val z: Int) +    val fooData = DataClassExample(1, 2, 4) +    println(fooData) // => DataClassExample(x=1, y=2, z=4) + +    // Data-классы обладают функцией "copy". +    val fooCopy = fooData.copy(y = 100) +    println(fooCopy) // => DataClassExample(x=1, y=100, z=4) + +    // Объекты могут быть деструктурированы на множество переменных. +    val (a, b, c) = fooCopy +    println("$a $b $c") // => 1 100 4 +     +    // Деструктурирование в цикле "for" +    for ((a, b, c) in listOf(fooData)) { +        println("$a $b $c") // => 1 100 4 +    } +     +    val mapData = mapOf("a" to 1, "b" to 2) +    // Map.Entry также может быть дествуктурирован +    for ((key, value) in mapData) { +        println("$key -> $value") +    } + +    // Функция "with" аналогична оператору "with" в JavaScript. +    data class MutableDataClassExample (var x: Int, var y: Int, var z: Int) +    val fooMutableData = MutableDataClassExample(7, 4, 9) +    with (fooMutableData) { +        x -= 2 +        y += 2 +        z-- +    } +    println(fooMutableData) // => MutableDataClassExample(x=5, y=6, z=8) + +    /* +    Можно создать список с помощью функции "ListOf". +    Этот список будет неизменяемым, т.е. элементы не могут быть удалены или добавлены в него. +    */ +    val fooList = listOf("a", "b", "c") +    println(fooList.size) // => 3 +    println(fooList.first()) // => a +    println(fooList.last()) // => c +    // Элементы списка доступны по их индексу в нем.  +    println(fooList[1]) // => b + +    // Изменяемый список может быть создан спомощью функции "mutableListOf". +    val fooMutableList = mutableListOf("a", "b", "c") +    fooMutableList.add("d") +    println(fooMutableList.last()) // => d +    println(fooMutableList.size) // => 4 + +    // Мы можем создать набор, используя функцию "setOf".  +    val fooSet = setOf("a", "b", "c") +    println(fooSet.contains("a")) // => true +    println(fooSet.contains("z")) // => false + +    // Мы можем создать отображение (map), используя функцию "mapOf". +    val fooMap = mapOf("a" to 8, "b" to 7, "c" to 9) +    // Получить доступ к значениям отображения (map) можно с помощью их ключа.  +    println(fooMap["a"]) // => 8 + +    /* +    Последовательности представляют собой коллекции с ленивой оценкой. +    Мы можем создать последовательность, используя функцию "generateSequence". +    */ +    val fooSequence = generateSequence(1, { it + 1 }) +    val x = fooSequence.take(10).toList() +    println(x) // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + +    // Пример использования последовательности для генерации чисел Фибоначчи: +    fun fibonacciSequence(): Sequence<Long> { +        var a = 0L +        var b = 1L + +        fun next(): Long { +            val result = a + b +            a = b +            b = result +            return a +        } + +        return generateSequence(::next) +    } +    val y = fibonacciSequence().take(10).toList() +    println(y) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] + +    // Kotlin предоставляет функции высшего порядка для работы с коллекциями. +    val z = (1..9).map {it * 3} +                  .filter {it < 20} +                  .groupBy {it % 2 == 0} +                  .mapKeys {if (it.key) "even" else "odd"} +    println(z) // => {odd=[3, 9, 15], even=[6, 12, 18]} + +    // Цикл "for" может использоваться со всем, что предоставляет  итератор. +    for (c in "hello") { +        println(c) +    } + +    // Циклы "while" работают также, как и в других языках. +    var ctr = 0 +    while (ctr < 5) { +        println(ctr) +        ctr++ +    } +    do { +        println(ctr) +        ctr++ +    } while (ctr < 10) + +    /* +    "if" может быть использован в качестве выражения, которое возвращает значение. +    По этой причине в Kotlin тернарный оператор ?: не нужен. +    */ +    val num = 5 +    val message = if (num % 2 == 0) "even" else "odd" +    println("$num is $message") // => 5 is odd + +    // "when" может быть использован как альтернатива цепочке "if-else if". +    val i = 10 +    when { +        i < 7 -> println("first block") +        fooString.startsWith("hello") -> println("second block") +        else -> println("else block") +    } + +    // "when" может быть использован с аргументами. +    when (i) { +        0, 21 -> println("0 or 21") +        in 1..20 -> println("in the range 1 to 20") +        else -> println("none of the above") +    } + +    // "when" также может быть использовано как функция, возвращающая значение. +    var result = when (i) { +        0, 21 -> "0 or 21" +        in 1..20 -> "in the range 1 to 20" +        else -> "none of the above" +    } +    println(result) + +    /* +    Мы можем проверить, что объект принадлежит к определенному типу, используя оператор "is". +    Если объект проходит проверку типа, то он может использоваться как этот тип без явной его  передачи. +    */ +    fun smartCastExample(x: Any) : Boolean { +        if (x is Boolean) { +            // x is automatically cast to Boolean +            return x +        } else if (x is Int) { +            // x is automatically cast to Int +            return x > 0 +        } else if (x is String) { +            // x is automatically cast to String +            return x.isNotEmpty() +        } else { +            return false +        } +    } +    println(smartCastExample("Hello, world!")) // => true +    println(smartCastExample("")) // => false +    println(smartCastExample(5)) // => true +    println(smartCastExample(0)) // => false +    println(smartCastExample(true)) // => true + +    // Smartcast также работает с блоком "when" +    fun smartCastWhenExample(x: Any) = when (x) { +        is Boolean -> x +        is Int -> x > 0 +        is String -> x.isNotEmpty() +        else -> false +    } + +    /* +    Расширения - это способ добавить новый функционал к классу.  +    Это то же самое, что методы расширений в C#. +    */ +    fun String.remove(c: Char): String { +        return this.filter {it != c} +    } +    println("Hello, world!".remove('l')) // => Heo, word! + +    println(EnumExample.A) // => A +    println(ObjectExample.hello()) // => hello +} + +// Enum-классы схожи с типами enum в Java. +enum class EnumExample { +    A, B, C +} + +/* +Ключевое слово "object" может использоваться для создания одноэлементных объектов. +Мы не можем его инстанцировать, но можем вызывать его уникальный экземпляр по имени. +Это похоже на одиночные объекты Scala. +*/ +object ObjectExample { +    fun hello(): String { +        return "hello" +    } +} + +fun useObject() { +    ObjectExample.hello() +    val someRef: Any = ObjectExample // we use objects name just as is +} + +``` + +### Дальнейшее чтение: + +* [Учебные материалы по Kotlin](https://kotlinlang.org/docs/tutorials/) +* [Попробуй Kotlin в своем браузере](http://try.kotlinlang.org/) +* [Список ресурсов по языку Kotlin](http://kotlin.link/) diff --git a/ru-ru/markdown-ru.html.markdown b/ru-ru/markdown-ru.html.markdown index eb8e4881..ff7a0cc3 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/nim-ru.html.markdown b/ru-ru/nim-ru.html.markdown new file mode 100644 index 00000000..d05583d7 --- /dev/null +++ b/ru-ru/nim-ru.html.markdown @@ -0,0 +1,279 @@ +--- +language: Nim +filename: learnNim-ru.nim +contributors: +    - ["Jason J. Ayala P.", "http://JasonAyala.com"] +    - ["Dennis Felsing", "http://felsin9.de/nnis/"] +translators: +    - ["Nomadic", "https://github.com/n0madic"] +lang: ru-ru +--- + +Nim (ранее известный, как Nimrod) — язык программирования со статической +типизацией, поддерживающий процедурный, объектно-ориентированный, +функциональный и обобщённый стили программирования. + +Nim эффективный, выразительный и элегантный. + +```nim +var                     # Объявление (и присваивание) переменных, +  letter: char = 'n'    # с указанием типа или без +  lang = "N" & "im" +  nLength : int = len(lang) +  boat: float +  truth: bool = false + +let            # Используйте let *сразу* для объявления и связывания переменных. +  legs = 400   # legs неизменяемый. +  arms = 2_000 # Символ _ игнорируется и удобен для длинных чисел. +  aboutPi = 3.15 + +const            # Константы вычисляются во время компиляции. Это обеспечивает +  debug = true   # производительность и полезно в выражениях этапа компиляции. +  compileBadCode = false + +when compileBadCode:            # `when` это `if` этапа компиляции. +  legs = legs + 1               # Эта ошибка никогда не будет скомпилирована. +  const input = readline(stdin) # Значения констант должны быть известны во +                                # время компиляции. + +discard 1 > 2 # Примечание. Компилятор будет жаловаться, если результат +              # выражения не используется. `discard` обходит это. + +discard """ +Это может использоваться как многострочный комментарий. +Или для не поддающегося синтаксическому анализу, сломанного кода +""" + +# +# Структуры данных +# + +# Кортежи + +var +  child: tuple[name: string, age: int]   # Кортежи определяют *как* имя поля +  today: tuple[sun: string, temp: float] # так *и* порядок полей. + +child = (name: "Rudiger", age: 2) # Присвоить все сразу литералом () +today.sun = "Overcast"            # или отдельно по полям. +today.temp = 70.1 + +# Последовательности + +var +  drinks: seq[string] + +drinks = @["Water", "Juice", "Chocolate"] # @[V1,..,Vn] является литералом +                                          # последовательности + +drinks.add("Milk") + +if "Milk" in drinks: +  echo "We have Milk and ", drinks.len - 1, " other drinks" + +let myDrink = drinks[2] + +# +# Определение типов +# + +# Определение собственных типов позволяет компилятору работать на вас. +# Это то, что делает статическую типизацию мощной и полезной. + +type +  Name = string # Псевдоним типа дает вам новый тип, который равнозначен +  Age = int     # старому типу, но более нагляден. +  Person = tuple[name: Name, age: Age] # Определение структур данных. +  AnotherSyntax = tuple +    fieldOne: string +    secondField: int + +var +  john: Person = (name: "John B.", age: 17) +  newage: int = 18 # Было бы лучше использовать Age, чем int + +john.age = newage # Но это все же работает, потому что int и Age синонимы. + +type +  Cash = distinct int    # `distinct` делает новый тип несовместимым с его +  Desc = distinct string # базовым типом. + +var +  money: Cash = 100.Cash # `.Cash` преобразует int в наш тип +  description: Desc  = "Interesting".Desc + +when compileBadCode: +  john.age  = money        # Error! age is of type int and money is Cash +  john.name = description  # Компилятор говорит: "Нельзя!" + +# +# Дополнительные типы и структуры данных +# + +# Перечисления позволяют типу иметь одно из ограниченного числа значений + +type +  Color = enum cRed, cBlue, cGreen +  Direction = enum # Альтернативный формат +    dNorth +    dWest +    dEast +    dSouth +var +  orient = dNorth # `orient` имеет тип Direction, со значением `dNorth` +  pixel = cGreen # `pixel` имеет тип Color, со значением `cGreen` + +discard dNorth > dEast # Перечисления обычно являются "порядковыми" типами + +# Поддиапазоны определяют ограниченный допустимый диапазон + +type +  DieFaces = range[1..20] # Допустимым значением являются только int от 1 до 20 +var +  my_roll: DieFaces = 13 + +when compileBadCode: +  my_roll = 23 # Error! + +# Arrays + +type +  RollCounter = array[DieFaces, int]  # Массивы фиксированной длины и +  DirNames = array[Direction, string] # индексируются любым порядковым типом. +  Truths = array[42..44, bool] +var +  counter: RollCounter +  directions: DirNames +  possible: Truths + +possible = [false, false, false] # Массивы создаются литералом [V1,..,Vn] +possible[42] = true + +directions[dNorth] = "Ahh. The Great White North!" +directions[dWest] = "No, don't go there." + +my_roll = 13 +counter[my_roll] += 1 +counter[my_roll] += 1 + +var anotherArray = ["Default index", "starts at", "0"] + +# Доступны другие структуры данных, в том числе таблицы, множества, +# списки, очереди и crit-bit деревья. +# http://nim-lang.org/docs/lib.html#collections-and-algorithms (EN) + +# +# IO и поток управления выполнением +# + +# `case`, `readLine()` + +echo "Read any good books lately?" +case readLine(stdin) +of "no", "No": +  echo "Go to your local library." +of "yes", "Yes": +  echo "Carry on, then." +else: +  echo "That's great; I assume." + +# `while`, `if`, `continue`, `break` + +import strutils as str # http://nim-lang.org/docs/strutils.html (EN) +echo "I'm thinking of a number between 41 and 43. Guess which!" +let number: int = 42 +var +  raw_guess: string +  guess: int +while guess != number: +  raw_guess = readLine(stdin) +  if raw_guess == "": continue # Пропустить эту итерацию +  guess = str.parseInt(raw_guess) +  if guess == 1001: +    echo("AAAAAAGGG!") +    break +  elif guess > number: +    echo("Nope. Too high.") +  elif guess < number: +    echo(guess, " is too low") +  else: +    echo("Yeeeeeehaw!") + +# +# Итерации (циклы) +# + +for i, elem in ["Yes", "No", "Maybe so"]: # Или просто `for elem in` +  echo(elem, " is at index: ", i) + +for k, v in items(@[(person: "You", power: 100), (person: "Me", power: 9000)]): +  echo v + +let myString = """ +an <example> +`string` to +play with +""" # Многострочная "сырая" строка + +for line in splitLines(myString): +  echo(line) + +for i, c in myString:       # Индекс и символ. Или `for j in` только для символов +  if i mod 2 == 0: continue # Компактная форма `if` +  elif c == 'X': break +  else: echo(c) + +# +# Процедуры +# + +type Answer = enum aYes, aNo + +proc ask(question: string): Answer = +  echo(question, " (y/n)") +  while true: +    case readLine(stdin) +    of "y", "Y", "yes", "Yes": +      return Answer.aYes  # Перечисления могут быть квалифицированы +    of "n", "N", "no", "No": +      return Answer.aNo +    else: echo("Please be clear: yes or no") + +proc addSugar(amount: int = 2) = # Значение поумолчанию 2, ничего не возвращает +  assert(amount > 0 and amount < 9000, "Crazy Sugar") +  for a in 1..amount: +    echo(a, " sugar...") + +case ask("Would you like sugar in your tea?") +of aYes: +  addSugar(3) +of aNo: +  echo "Oh do take a little!" +  addSugar() +# Здесь нет необходимости в `else`. Возможны только `yes` и `no`. + +# +# FFI (интерфейс внешних функций) +# + +# Так как Nim компилируется в C, то FFI делается очень просто: + +proc strcmp(a, b: cstring): cint {.importc: "strcmp", nodecl.} + +let cmp = strcmp("C?", "Easy!") +``` + +Кроме того, Nim выделяется среди себе подобных метапрограммированием, +производительностью, функциями этапа компиляции. + +## Дальнейшее чтение (EN) + +* [Домашняя страница](http://nim-lang.org) +* [Скачать](http://nim-lang.org/download.html) +* [Сообщество](http://nim-lang.org/community.html) +* [FAQ](http://nim-lang.org/question.html) +* [Документация](http://nim-lang.org/documentation.html) +* [Руководство](http://nim-lang.org/docs/manual.html) +* [Стандартная библиотека](http://nim-lang.org/docs/lib.html) +* [Rosetta Code](http://rosettacode.org/wiki/Category:Nim) diff --git a/ru-ru/php-ru.html.markdown b/ru-ru/php-ru.html.markdown index 37b6a86e..181368de 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,10 +55,13 @@ $boolean = false; // или FALSE или False  // Целые числа  $int1 = 12;   // => 12 -$int2 = -12;  // => -12- +$int2 = -12;  // => -12  $int3 = 012;  // => 10 (ведущий 0 обозначает восьмеричное число)  $int4 = 0x0F; // => 15 (ведущие символы 0x означают шестнадцатеричное число) +// Двоичная запись integer доступна начиная с PHP 5.4.0. +$int5 = 0b11111111; // 255 (0b в начале означает двоичное число) +  // Дробные числа  $float = 1.234;  $float = 1.2e3; @@ -87,7 +90,9 @@ $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'; -// Заключайте переменные в фигурные скобки если это необходимо +// Заключайте переменные в фигурные скобки, если это необходимо +$apples = "I have {$number} apples to eat."; +$oranges = "I have ${number} oranges to eat.";  $money = "I have $${number} in the bank.";  // Начиная с PHP 5.3, синтаксис nowdocs может использоваться для @@ -106,6 +111,9 @@ END;  // Строки соединяются при помощи .  echo 'This string ' . 'is concatenated'; +// echo можно передавать строки как параметры +echo 'Multiple', 'Parameters', 'Valid'; // печатает 'MultipleParametersValid' +  /********************************   * Константы @@ -114,18 +122,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. @@ -136,11 +145,20 @@ $associative = array('One' => 1, 'Two' => 2, 'Three' => 3);  $associative = ['One' => 1, 'Two' => 2, 'Three' => 3];  echo $associative['One']; // печатает 1 +// Добавить элемент в ассоциативный массив +$associative['Four'] = 4; +  // Список тоже содержит целочисленные ключи  $array = ['One', 'Two', 'Three'];  echo $array[0]; // => "One" +// Добавить элемент в конец массива +$array[] = 'Four'; +// или +array_push($array, 'Five'); +// удалить элемент из массива +unset($array[3]);  /********************************   * Вывод @@ -180,6 +198,10 @@ $y = 0;  echo $x; // => 2  echo $z; // => 0 +// Вывести тип и значение переменной в stdout +var_dump($z); // печатает int(0) +// Напечатать переменную в stdout в удобочитаемом виде +print_r($array); // печатает: Array ( [0] => One [1] => Two [2] => Three )  /********************************   * Логические выражения @@ -189,7 +211,7 @@ $b = '0';  $c = '1';  $d = '1'; -// Утверждение (assert) выдает предупреждение если аргумент не true +// Утверждение (assert) выдает предупреждение, если его аргумент не true  // Эти сравнения всегда будут истинными, даже если типы будут различаться  assert($a == $b); // "равно" @@ -200,12 +222,21 @@ assert($c > $b); // больше  assert($a <= $b); // меньше или равно  assert($c >= $d); // больше или равно -// Следующие утверждения истинны, если переменные имеют одинаковый тип. +// Следующие утверждения истинны, если переменные имеют одинаковые тип.  assert($c === $d);  assert($a !== $d);  assert(1 == '1');  assert(1 !== '1'); +// 'Spaceship' оператор (с PHP 7) используется для сравнения двух выражений. +// Возвращает -1, 0 или 1, когда выражение слева меньше, равно или больше +// выражения справа. +$a = 100; +$b = 1000; + +echo $a <=> $a; // 0, выражения равны +echo $a <=> $b; // -1, $a < $b +echo $b <=> $a; // 1, $b > $a  // Переменные могут изменять тип в зависимости от их использования.  $integer = 1;  echo $integer + $integer; // => 2 @@ -261,6 +292,11 @@ if (false) {  // Тернарный оператор  print (false ? 'Does not get printed' : 'Does'); +// сокращенная запись тернарного оператора с PHP 5.3 +// эквивалентно "$x ? $x : 'Does'" +$x = false; +print($x ?: 'Does'); +  $x = 0;  if ($x === '0') {      print 'Does not print'; @@ -284,35 +320,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 +371,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 +396,7 @@ function my_function () {  echo my_function(); // => "Hello"  // Правильное имя функции начинается с буквы или символа подчеркивания -// и состоит из букв, цифр или знаков подчеркивания. +// и состоит из букв, цифр или символов подчеркивания.  function add ($x, $y = 1) { // $y по умолчанию равно 1    $result = $x + $y; @@ -447,7 +483,7 @@ $value = include 'my-include.php';  class MyClass  { -    const MY_CONST      = 'value'; // A constant +    const MY_CONST      = 'value'; // Константа      static $staticVar   = 'static'; @@ -651,12 +687,167 @@ use My\Namespace as SomeOtherNamespace;  $cls = new SomeOtherNamespace\MyClass(); +*//********************** +* Позднее статическое связывание. +* +*/ + +class ParentClass +{ +    public static function who() +    { +        echo "I'm a " . __CLASS__ . "\n"; +    } + +    public static function test() +    { +        // self ссылается на класс в котором определен метод. +        self::who(); +        // static ссылается на класс в котором метод вызван. +        static::who(); +    } +} + +ParentClass::test(); +/* +I'm a ParentClass +I'm a ParentClass +*/ + +class ChildClass extends ParentClass +{ +    public static function who() +    { +        echo "But I'm " . __CLASS__ . "\n"; +    } +} + +ChildClass::test(); +/* +I'm a ParentClass +But I'm ChildClass + +/********************** +* Позднее статическое связывание. +* +*/ + +class ParentClass +{ +    public static function who() +    { +        echo "I'm a " . __CLASS__ . "\n"; +    } + +    public static function test() +    { +        // self ссылается на класс в котором определен метод. +        self::who(); +        // static ссылается на класс в котором метод вызван. +        static::who(); +    } +} + +ParentClass::test(); +/* +I'm a ParentClass +I'm a ParentClass +*/ + +class ChildClass extends ParentClass +{ +    public static function who() +    { +        echo "But I'm " . __CLASS__ . "\n"; +    } +} + +ChildClass::test(); +/* +I'm a ParentClass +But I'm ChildClass +*/ + + +/********************** +*  Магические константы +* +*/ + +// Возвращает имя текущего класса. Должно быть использовано внутри класса. +echo "Current class name is " . __CLASS__; + +// Возвращает полный путь текущей папки из которой вызван файл. +echo "Current directory is " . __DIR__; + +    // Обычно используют в таких случаях: +    require __DIR__ . '/vendor/autoload.php'; + +// Возвращает полный путь к текущему файлу. +echo "Current file path is " . __FILE__; + +// Возвращает имя текущей функции. +echo "Current function name is " . __FUNCTION__; + +// Возвращает номер текущей линии. +echo "Current line number is " . __LINE__; + +// Возвращает имя текущего метода. Возвращает только если вызван внутри метода. +echo "Current method is " . __METHOD__; + +// Возвращает имя текущего пространства имен. +echo "Current namespace is " . __NAMESPACE__; + +// Возвращает имя текущего трейта. +// Возвращает только если испольщуется внутри трейта. +echo "Current namespace is " . __TRAIT__; + + +/********************** +*  Обработка ошибок +*    */ +// Простую обработку ошибок можно произвести спомощью try catch блока. + +try { +    // Выполняем что-то +} catch (Exception $e) { +    // Обработка исключения +} + +// При использовании try catch блока в области вилимости, стоит использовать +// следующий подход: + +try { +    // Do something +} catch (\Exception $e) { +    // Обработка исключения +} + +// Специальное(кастомное) исключение - exceptions + +class MyException extends Exception {} + +try { + +    $condition = true; + +    if ($condition) { +        throw new MyException('Something just happend'); +    } + +} catch (MyException $e) { +    // Обработка исключения +} +  ```  ## Смотрите также: -Посетите страницу [официальной документации 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).  + +Для изучения стандартов использования языка посетите PHP Framework Interoperability Group's [PSR standards](https://github.com/php-fig/fig-standards). diff --git a/ru-ru/pyqt-ru.html.markdown b/ru-ru/pyqt-ru.html.markdown new file mode 100644 index 00000000..24afc03d --- /dev/null +++ b/ru-ru/pyqt-ru.html.markdown @@ -0,0 +1,86 @@ +--- +category: tool +tool: PyQT +lang: ru-ru +filename: learnpyqt-ru.py +contributors: +    - ["Nathan Hughes", "https://github.com/sirsharpest"] +translators: +    - ["Vadim Toptunov", "https://github.com/VadimToptunov"] +--- + +**Qt** - широко известный кросс-платформенный фреймворк для разработки программного обеспечения, +который может быть использован на различных софтварных и хардварных платформах без какого-либо +изменения в коде. Данный фреймворк при этом обладает мощью и скоростью нативных приложений.  +Qt и был изначально написан на *C++*. + +Данный текст является адаптацией введения в Qt на C++ под авторством Алексея Ковальчука для pyqt. + + +```python + +def window(): +    # Создайте объект приложения  +    app = QtGui.QApplication(sys.argv) +    # Создайте виджет, где будет находиться наш лейбл +    w = QtGui.QWidget() +    # Добавьте лейбл в виджет +    b = QtGui.QLabel(w) +    # Задайте текст для лейбла +    b.setText("Hello World!") +    # Задайте информация о размере и расположении  +    w.setGeometry(100, 100, 200, 50) +    b.move(50, 20) +    # Задайте заголовок окна  +    w.setWindowTitle("PyQt") +    # Все ранее написанное выводится на экран +    w.show() +    # Настройка +    sys.exit(app.exec_()) + +if __name__ == '__main__': +    window() + +``` + +Для того, чтобы получить более продвинутые функции приложения в pyqt, нам необходимо  +обратить внимание на создание дополнительных элементов. Ниже представлено создание всплывающего диалогового окна, которое просит пользователя подтвердить его решение или предоставить какую-либо  +информацию. + +```Python  +import sys +from PyQt4.QtGui import * +from PyQt4.QtCore import * + + +def window(): +    app = QApplication(sys.argv) +    w = QWidget() +    # Создайте кнопку и прикрепите ее к виджету w +    b = QPushButton(w) +    b.setText("Press me") +    b.move(50, 50) +    # Укажите b вызвать эту функцию при клике мышкой +    # Заметьте, что в вызове функции отсутствуют "()" +    b.clicked.connect(showdialog) +    w.setWindowTitle("PyQt Dialog") +    w.show() +    sys.exit(app.exec_()) + +Данная функция должна создавать диалоговое окно с кнопкой, которая ждет клика по себе  +и затем завершает программу. + +def showdialog(): +    d = QDialog() +    b1 = QPushButton("ok", d) +    b1.move(50, 50) +    d.setWindowTitle("Dialog") +    # Эта модальность сообщает всплывающему окну блокировать родительский элемент, пока он активен +    d.setWindowModality(Qt.ApplicationModal) +    # Процесс завершается по клику мышкой +    b1.clicked.connect(sys.exit) +    d.exec_() + +if __name__ == '__main__': +    window() +``` diff --git a/ru-ru/qt-ru.html.markdown b/ru-ru/qt-ru.html.markdown new file mode 100644 index 00000000..d0a70c9d --- /dev/null +++ b/ru-ru/qt-ru.html.markdown @@ -0,0 +1,158 @@ +--- +category: tool +tool: Qt Framework +language: c++ +filename: learnqt-ru.cpp +contributors: +    - ["Aleksey Kholovchuk", "https://github.com/vortexxx192"] +translators: +    - ["Evan K.", "https://github.com/justblah"] +lang: ru-ru +--- + +**Qt** является широко известным фреймворком для разработки кросс-платформенного программного обеспечения, которое может быть запущено на различных программно-аппаратных платформах практически без изменений в коде, сохраняя при этом мощность и скорость нативных приложений. Хоть **Qt** и был изначально написан на *C++*, у него есть реализации и на других языках: *PyQt*, *QtRuby*, *PHP-Qt* и т.д. + +**Qt** отлично подходит для создания приложений с графическим пользовательским интерфейсом (GUI). Это руководство о том, как сделать это на *C++*. + +```c++ +/* + * Начнём по-старинке + */ + +// все header файлы импортированные из Qt начинаются с заглавной 'Q' +#include <QApplication> +#include <QLineEdit> + +int main(int argc, char *argv[]) { +    // создаем объект для управления данными приложения +    QApplication app(argc, argv); + +    // создаем редактируемую строку и отобразим её на экране +    QLineEdit lineEdit("Hello world!"); +    lineEdit.show(); + +    // запускаем цикл для обработки событий (event loop) +    return app.exec(); +} +``` + +GUI часть **Qt** полностью состоит из *виджетов* и *связей* между ними. + +[(EN) ПОДРОБНЕЕ О ВИДЖЕТАХ](http://doc.qt.io/qt-5/qtwidgets-index.html) + +```c++ +/* + * В этом примере мы отобразим надпись с кнопкой. + * Надпись будет появляться после нажатия на кнопку. + * + * Код на Qt говорит сам за себя. + */ + +#include <QApplication> +#include <QDialog> +#include <QVBoxLayout> +#include <QPushButton> +#include <QLabel> + +int main(int argc, char *argv[]) { +    QApplication app(argc, argv); + +    QDialog dialogWindow; +    dialogWindow.show(); + +    // добавляем вертикальное расположение +    QVBoxLayout layout; +    dialogWindow.setLayout(&layout);   + +    QLabel textLabel("Thanks for pressing that button"); +    layout.addWidget(&textLabel); +    textLabel.hide(); + +    QPushButton button("Press me"); +    layout.addWidget(&button); + +    // отображаем скрытую надпись после нажатия на кнопку +    QObject::connect(&button, &QPushButton::pressed, +                     &textLabel, &QLabel::show); + +    return app.exec(); +} +``` +Обратите внимание на метод *QObject::connect*. Этот метод соединяет *СИГНАЛЫ* одного объекта со *СЛОТАМИ* другого. + +**Сигналы** отправляются когда с объектами происходят отпределённые события, например, сигнал *нажатие* отправляется когда пользователь нажимает на объект типа QPushButton. + +**Слоты** это *действия*, которые могут быть выполнены в ответ на полученные сигналы. + +[(EN) ПОДРОБНЕЕ О СЛОТАХ И СИГНАЛАХ](http://doc.qt.io/qt-4.8/signalsandslots.html) + + +Далее рассмотрим, как можно не только использовать стандартные виджеты, но и расширять их поведение с помощью наследования. Давайте создадим кнопку и посчитаем, сколько раз она была нажата. Для этого мы определяем наш собственный класс *CounterLabel*. Он должен быть объявлен в отдельном файле из-за специфической архитектуры Qt. + +```c++ +// counterlabel.hpp + +#ifndef COUNTERLABEL +#define COUNTERLABEL + +#include <QLabel> + +class CounterLabel : public QLabel { +    Q_OBJECT  // макрос Qt, обязателен для всех виджетов + +public: +    CounterLabel() : counter(0) { +        setText("Counter has not been increased yet");  // метод QLabel +    } + +public slots: +    // действие, которое будет вызвано в ответ на нажатие +    void increaseCounter() { +        setText(QString("Counter value: %1").arg(QString::number(++counter))); +    } + +private: +    int counter; +}; + +#endif // COUNTERLABEL +``` + +```c++ +// main.cpp +// Почти тоже самое, что и в предыдущем примере + +#include <QApplication> +#include <QDialog> +#include <QVBoxLayout> +#include <QPushButton> +#include <QString> +#include "counterlabel.hpp" + +int main(int argc, char *argv[]) { +    QApplication app(argc, argv); + +    QDialog dialogWindow; +    dialogWindow.show(); + +    QVBoxLayout layout; +    dialogWindow.setLayout(&layout); + +    CounterLabel counterLabel; +    layout.addWidget(&counterLabel); + +    QPushButton button("Push me once more"); +    layout.addWidget(&button); +    QObject::connect(&button, &QPushButton::pressed, +                     &counterLabel, &CounterLabel::increaseCounter); + +    return app.exec(); +} +``` + +## На почитать +Это всё! Конечно, фреймворк Qt намного объемнее, чем часть, которая была рассмотрена в этом руководстве, так что будьте готовы читать и практиковаться. + +[(EN) ДОКУМЕНТАЦИЯ](http://wiki.qt.io/Main/ru) + +Удачи! diff --git a/ru-ru/swift-ru.html.markdown b/ru-ru/swift-ru.html.markdown index 77987bb3..7ff660e1 100644 --- a/ru-ru/swift-ru.html.markdown +++ b/ru-ru/swift-ru.html.markdown @@ -4,9 +4,11 @@ contributors:    - ["Grant Timmerman", "http://github.com/grant"]    - ["Christopher Bess", "http://github.com/cbess"]    - ["Joey Huang", "http://github.com/kamidox"] +  - ["Alexey Nazaroff", "http://github.com/rogaven"]  filename: learnswift-ru.swift  translators:    - ["Dmitry Bessonov", "https://github.com/TheDmitry"] +  - ["Alexey Nazaroff", "https://github.com/rogaven"]  lang: ru-ru  --- @@ -21,6 +23,8 @@ Swift - это язык программирования, созданный к  Смотрите еще [начальное руководство](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/RoadMapiOS/index.html) Apple, которое содержит полное учебное пособие по Swift.  ```swift +// Версия Swift: 3.0 +  // импорт модуля  import UIKit @@ -31,10 +35,14 @@ import UIKit  // Xcode поддерживает маркеры, чтобы давать примечания своему коду  // и вносить их в список обозревателя (Jump Bar)  // MARK: Метка раздела +// MARK: - Метка с разделителем  // TODO: Сделайте что-нибудь вскоре  // FIXME: Исправьте этот код -println("Привет, мир") +// Начиная со второй версии Swift, println и print объединены в методе print. +// Перенос строки теперь добавляется в конец автоматически. +print("Привет, мир!") // println – теперь просто print +print("Привет, мир!", terminator: "") // вывод текста без переноса строки  // переменные (var), значение которых можно изменить после инициализации  // константы (let), значение которых нельзя изменить после инициализации @@ -56,12 +64,12 @@ let piText = "Pi = \(π), Pi 2 = \(π * 2)" // Вставка переменны  // Сборка особых значений  // используя ключ -D сборки конфигурации  #if false -    println("Не печатается") +    print("Не печатается")      let buildValue = 3  #else      let buildValue = 7  #endif -println("Значение сборки: \(buildValue)") // Значение сборки: 7 +print("Значение сборки: \(buildValue)") // Значение сборки: 7  /*      Опционалы - это особенность языка Swift, которая допускает вам сохранять @@ -79,35 +87,45 @@ var someOptionalString2: Optional<String> = "опционал"  if someOptionalString != nil {      // я не nil      if someOptionalString!.hasPrefix("opt") { -        println("содержит префикс") +        print("содержит префикс")      } -     +      let empty = someOptionalString?.isEmpty  }  someOptionalString = nil +/* +Использование ! для доступа к несуществующему опциональному значению генерирует +рантайм ошибку. Всегда проверяйте, что опционал содержит не пустое значение, +перед тем как раскрывать его через !. +*/ +  // неявная развертка опциональной переменной  var unwrappedString: String! = "Ожидаемое значение."  // как и выше, только ! - постфиксный оператор (с еще одним синтаксическим сахаром)  var unwrappedString2: ImplicitlyUnwrappedOptional<String> = "Ожидаемое значение." +// If let конструкции - +// If let это специальная конструкция в Swift, которая позволяет проверить Optional +// справа от `=` непустой, и если это так - разворачивает его и присваивает левой части.  if let someOptionalStringConstant = someOptionalString { -    // имеется некоторое значение, не nil +    // имеется некоторое (`Some`) значение, не `nil`      if !someOptionalStringConstant.hasPrefix("ok") {          // нет такого префикса      }  }  // Swift поддерживает сохранение значения любого типа +// Для этих целей есть два ключевых слова `Any` и `AnyObject`  // AnyObject == id -// В отличие от `id` в Objective-C, AnyObject работает с любым значением (Class, -// Int, struct и т.д.) -var anyObjectVar: AnyObject = 7 -anyObjectVar = "Изменять значение на строку не является хорошей практикой, но возможно." +// `Any` же, в отличие от `id` в Objective-C, `Any` работает с любым значением (Class, Int, struct и т.д.) +var anyVar: Any = 7 +anyVar = "Изменять значение на строку не является хорошей практикой, но возможно." +let anyObjectVar: AnyObject = Int(1) as NSNumber  /*      Комментируйте здесь -     +      /*          Вложенные комментарии тоже поддерживаются      */ @@ -129,6 +147,7 @@ shoppingList[1] = "бутылка воды"  let emptyArray = [String]() // let == неизменный  let emptyArray2 = Array<String>() // как и выше  var emptyMutableArray = [String]() // var == изменяемый +var explicitEmptyMutableStringArray: [String] = [] // так же как и выше  // Словарь @@ -140,31 +159,39 @@ occupations["Jayne"] = "Связи с общественностью"  let emptyDictionary = [String: Float]() // let == неизменный  let emptyDictionary2 = Dictionary<String, Float>() // как и выше  var emptyMutableDictionary = [String: Float]() // var == изменяемый +var explicitEmptyMutableDictionary: [String: Float] = [:] // то же  //  // MARK: Поток управления  // +// С помощью "," можно указать дополнительные условия для раскрытия +// опциональных значений. +let someNumber = Optional<Int>(7) +if let num = someNumber, num > 3 { +    print("Больше 3х") +} +  // цикл for для массива  let myArray = [1, 1, 2, 3, 5]  for value in myArray {      if value == 1 { -        println("Один!") +        print("Один!")      } else { -        println("Не один!") +        print("Не один!")      }  }  // цикл for для словаря  var dict = ["один": 1, "два": 2]  for (key, value) in dict { -    println("\(key): \(value)") +    print("\(key): \(value)")  }  // цикл for для диапазона чисел  for i in -1...shoppingList.count { -    println(i) +    print(i)  }  shoppingList[1...2] = ["бифштекс", "орехи пекан"]  // используйте ..< для исключения последнего числа @@ -176,8 +203,8 @@ while i < 1000 {  }  // цикл do-while -do { -    println("привет") +repeat { +    print("привет")  } while 1 == 2  // Переключатель @@ -204,7 +231,7 @@ default: // обязательный (чтобы предусмотреть вс  // Функции являются типом первого класса, т.е. они могут быть вложены в функциях  // и могут передаваться между собой -// Функция с документированным заголовком Swift (формат reStructedText) +// Функция с документированным заголовком Swift (формат Swift-модифицированный Markdown)  /**      Операция приветствия @@ -212,20 +239,20 @@ default: // обязательный (чтобы предусмотреть вс      - Маркер в документировании      - Еще один маркер в документации -    :param: name - это имя -    :param: day - это день -    :returns: Строка, содержащая значения name и day. +    - Parameter name	: Это имя +    - Parameter day	: Это день +    - Returns : Строка, содержащая значения name и day.  */  func greet(name: String, day: String) -> String {      return "Привет \(name), сегодня \(day)."  } -greet("Боб", "вторник") +greet(name: "Боб", day: "вторник")  // как и выше, кроме обращения параметров функции -func greet2(#requiredName: String, externalParamName localParamName: String) -> String { -    return "Привет \(requiredName), сегодня \(localParamName)" +func greet2(name: String, externalParamName localParamName: String) -> String { +    return "Привет \(name), сегодня \(localParamName)"  } -greet2(requiredName:"Иван", externalParamName: "воскресенье") +greet2(name: "Иван", externalParamName: "Воскресенье")  // Функция, которая возвращает множество элементов в кортеже  func getGasPrices() -> (Double, Double, Double) { @@ -235,8 +262,31 @@ let pricesTuple = getGasPrices()  let price = pricesTuple.2 // 3.79  // Пропускайте значения кортежей с помощью подчеркивания _  let (_, price1, _) = pricesTuple // price1 == 3.69 -println(price1 == pricesTuple.1) // вывод: true -println("Цена газа: \(price)") +print(price1 == pricesTuple.1) // вывод: true +print("Цена газа: \(price)") + +// Именованные параметры кортежа +func getGasPrices2() -> (lowestPrice: Double, highestPrice: Double, midPrice: Double) { +    return (1.77, 37.70, 7.37) +} +let pricesTuple2 = getGasPrices2() +let price2 = pricesTuple2.lowestPrice +let (_, price3, _) = pricesTuple2 +print(pricesTuple2.highestPrice == pricesTuple2.1) // вывод: true +print("Самая высокая цена за газ: \(pricesTuple2.highestPrice)") + +// guard утверждения +func testGuard() { +    // guards обеспечивают прерывание дальнейшего выполнения функции, +    // позволяя держать обработчики ошибок рядом с проверкой условия +    // Объявляемая переменная находится в той же области видимости, что и guard. +    guard let aNumber = Optional<Int>(7) else { +        return +    } + +    print("число равно \(aNumber)") +} +testGuard()  // Переменное число аргументов  func setup(numbers: Int...) { @@ -246,7 +296,7 @@ func setup(numbers: Int...) {  }  // Передача и возврат функций -func makeIncrementer() -> (Int -> Int) { +func makeIncrementer() -> ((Int) -> Int) {      func addOne(number: Int) -> Int {          return 1 + number      } @@ -256,15 +306,15 @@ var increment = makeIncrementer()  increment(7)  // передача по ссылке -func swapTwoInts(inout a: Int, inout b: Int) { +func swapTwoInts(a: inout Int, b: inout Int) {      let tempA = a      a = b      b = tempA  }  var someIntA = 7  var someIntB = 3 -swapTwoInts(&someIntA, &someIntB) -println(someIntB) // 7 +swapTwoInts(a: &someIntA, b: &someIntB) +print(someIntB) // 7  // @@ -291,13 +341,13 @@ numbers = numbers.map({ number in 3 * number })  print(numbers) // [3, 6, 18]  // Хвостовое замыкание -numbers = sorted(numbers) { $0 > $1 } +numbers = numbers.sorted { $0 > $1 }  print(numbers) // [18, 6, 3]  // Суперсокращение, поскольку оператор < выполняет логический вывод типов -numbers = sorted(numbers, < ) +numbers = numbers.sorted(by: <)  print(numbers) // [3, 6, 18] @@ -307,8 +357,8 @@ print(numbers) // [3, 6, 18]  // Структуры и классы имеют очень похожие характеристики  struct NamesTable { -    let names = [String]() -     +    let names: [String] +      // Пользовательский индекс      subscript(index: Int) -> String {          return names[index] @@ -316,9 +366,48 @@ struct NamesTable {  }  // У структур автогенерируемый (неявно) инициализатор -let namesTable = NamesTable(names: ["Me", "Them"]) +let namesTable = NamesTable(names: ["Иван", "Яков"])  let name = namesTable[1] -println("Name is \(name)") // Name is Them +print("Имя :\(name)") // Имя: Яков + +// +// MARK: Обработка ошибок +// + +// Протокол `Error` используется для перехвата выбрасываемых ошибок +enum MyError: Error { +    case BadValue(msg: String) +    case ReallyBadValue(msg: String) +} + +// фунции помеченные словом `throws` должны вызываться с помощью `try` +func fakeFetch(value: Int) throws -> String { +    guard 7 == value else { +        throw MyError.ReallyBadValue(msg: "Действительно плохое значение") +    } + +    return "тест" +} + +func testTryStuff() { +    // предполагается, что не будет выброшено никаких ошибок, +    // в противном случае мы получим рантайм исключение +    let _ = try! fakeFetch(value: 7) + +    // Если возникает ошибка, то выполнение продолжится. Но если значение равно nil, +    // то результат будет опционалом +    let _ = try? fakeFetch(value: 7) + +    do { +        // обычно try оператор, позволяющий обработать ошибку в `catch` блоке +        try fakeFetch(value: 1) +    } catch MyError.BadValue(let msg) { +        print("Ошибка: \(msg)") +    } catch { +        // все остальное +    } +} +testTryStuff()  //  // MARK: Классы @@ -329,7 +418,7 @@ println("Name is \(name)") // Name is Them  public class Shape {      public func getArea() -> Int { -        return 0; +        return 0      }  } @@ -339,7 +428,7 @@ public class Shape {  internal class Rect: Shape {      var sideLength: Int = 1 -     +      // Пользовательский сеттер и геттер      private var perimeter: Int {          get { @@ -350,12 +439,17 @@ internal class Rect: Shape {              sideLength = newValue / 4          }      } -     + +    // Вычисляемые свойства должны быть объявлены с помощью `var`, ведь они могут меняться +    var smallestSideLength: Int { +        return self.sideLength - 1 +    } +      // Ленивая загрузка свойства      // свойство subShape остается равным nil (неинициализированным),      // пока не вызовется геттер      lazy var subShape = Rect(sideLength: 4) -     +      // Если вам не нужны пользовательские геттеры и сеттеры,      // но все же хотите запустить код перед и после вызовов геттера или сеттера      // свойств, вы можете использовать `willSet` и `didSet` @@ -365,19 +459,19 @@ internal class Rect: Shape {              print(someIdentifier)          }      } -     +      init(sideLength: Int) {          self.sideLength = sideLength          // последним всегда вызывается super.init, когда init с параметрами          super.init()      } -     +      func shrink() {          if sideLength > 0 { -            --sideLength +            sideLength -= 1          }      } -     +      override func getArea() -> Int {          return sideLength * sideLength      } @@ -400,7 +494,7 @@ let aShape = mySquare as Shape  // сравнение экземпляров, в отличие от ==, которая проверяет эквивалентность  if mySquare === mySquare { -    println("Ага, это mySquare") +    print("Ага, это mySquare")  }  // Опциональная инициализация (init) @@ -409,13 +503,13 @@ class Circle: Shape {      override func getArea() -> Int {          return 3 * radius * radius      } -     +      // Поместите постфиксный знак вопроса после `init` - это и будет опциональная инициализация,      // которая может вернуть nil      init?(radius: Int) {          self.radius = radius          super.init() -         +          if radius <= 0 {              return nil          } @@ -423,13 +517,13 @@ class Circle: Shape {  }  var myCircle = Circle(radius: 1) -println(myCircle?.getArea())    // Optional(3) -println(myCircle!.getArea())    // 3 +print(myCircle?.getArea())    // Optional(3) +print(myCircle!.getArea())    // 3  var myEmptyCircle = Circle(radius: -1) -println(myEmptyCircle?.getArea())    // "nil" +print(myEmptyCircle?.getArea())    // "nil"  if let circle = myEmptyCircle {      // не будет выполняться, поскольку myEmptyCircle равен nil -    println("circle не nil") +    print("circle не nil")  } @@ -456,12 +550,13 @@ enum Suit {  // указывать тип перечисления, когда переменная объявляется явно  var suitValue: Suit = .Hearts -// Нецелочисленные перечисления требуют прямого указания значений +// Значения нецелочисленных перечислений должны быть указаны явно +// или могут выводится с помощью функции `rawValue` из имени  enum BookName: String { -    case John = "Иоанн" +    case John      case Luke = "Лука"  } -println("Имя: \(BookName.John.rawValue)") +print("Имя: \(BookName.John.rawValue)")  // Перечисление (enum) со связанными значениями  enum Furniture { @@ -469,7 +564,7 @@ enum Furniture {      case Desk(height: Int)      // Связать с типами String и Int      case Chair(String, Int) -     +      func description() -> String {          switch self {          case .Desk(let height): @@ -481,9 +576,9 @@ enum Furniture {  }  var desk: Furniture = .Desk(height: 80) -println(desk.description())     // "Письменный стол высотой 80 см." +print(desk.description())     // "Письменный стол высотой 80 см."  var chair = Furniture.Chair("Foo", 40) -println(chair.description())    // "Стул марки Foo высотой 40 см." +print(chair.description())    // "Стул марки Foo высотой 40 см."  // @@ -500,23 +595,24 @@ protocol ShapeGenerator {  }  // Протоколы, объявленные с @objc, допускают необязательные функции, -// которые позволяют вам проверять на соответствие +// которые позволяют вам проверять на соответствие. Для функций также необходимо указать @objc  @objc protocol TransformShape { -    optional func reshaped() -    optional func canReshape() -> Bool +    @objc optional func reshape() +    @objc optional func canReshape() -> Bool  }  class MyShape: Rect {      var delegate: TransformShape? -     +      func grow() {          sideLength += 2 +          // Размещайте знак вопроса перед опционным свойством, методом          // или индексом, чтобы не учитывать nil-значение и возвратить nil          // вместо выбрасывания ошибки выполнения (т.н. "опционная цепочка") -        if let allow = self.delegate?.canReshape?() { +        if let reshape = self.delegate?.canReshape?(), reshape {              // проверка делегата на выполнение метода -            self.delegate?.reshaped?() +            self.delegate?.reshape?()          }      }  } @@ -528,42 +624,42 @@ class MyShape: Rect {  // `extension`s: Добавляет расширенный функционал к существующему типу -// Класс Square теперь "соответствует" протоколу `Printable` -extension Square: Printable { +// Класс Square теперь "соответствует" протоколу `CustomStringConvertible` +extension Square: CustomStringConvertible {      var description: String {          return "Площадь: \(self.getArea()) - ID: \(self.identifier)"      }  } -println("Объект Square: \(mySquare)") +print("Объект Square: \(mySquare)")  // Вы также можете расширить встроенные типы  extension Int {      var customProperty: String {          return "Это \(self)"      } -     +      func multiplyBy(num: Int) -> Int {          return num * self      }  } -println(7.customProperty) // "Это 7" -println(14.multiplyBy(3)) // 42 +print(7.customProperty) // "Это 7" +print(14.multiplyBy(num: 3)) // 42  // Обобщения: Подобно языкам Java и C#. Используйте ключевое слово `where`,  // чтобы определить условия обобщений.  func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? { -    for (index, value) in enumerate(array) { +    for (index, value) in array.enumerated() {          if value == valueToFind {              return index          }      }      return nil  } -let foundAtIndex = findIndex([1, 2, 3, 4], 3) -println(foundAtIndex == 2) // вывод: true +let foundAtIndex = findIndex(array: [1, 2, 3, 4], valueToFind: 3) +print(foundAtIndex == 2) // вывод: true  // Операторы:  // Пользовательские операторы могут начинаться с символов: @@ -571,19 +667,33 @@ println(foundAtIndex == 2) // вывод: true  // или  // Unicode- знаков математики, символов, стрелок, декорации и линий/кубов,  // нарисованных символов. -prefix operator !!! {} +prefix operator !!!  // Префиксный оператор, который утраивает длину стороны, когда используется -prefix func !!! (inout shape: Square) -> Square { +prefix func !!! (shape: inout Square) -> Square {      shape.sideLength *= 3      return shape  }  // текущее значение -println(mySquare.sideLength) // 4 +print(mySquare.sideLength) // 4  // Используя пользовательский оператор !!!, изменится длина стороны  // путем увеличения размера в 3 раза  !!!mySquare -println(mySquare.sideLength) // 12 +print(mySquare.sideLength) // 12 + +// Операторы также могут быть обобщенными +infix operator <-> +func <-><T: Equatable> (a: inout T, b: inout T) { +    let c = a +    a = b +    b = c +} + +var foo: Float = 10 +var bar: Float = 20 + +foo <-> bar +print("foo это \(foo), bar это \(bar)") // "foo = 20.0, bar = 10.0"  ``` 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..09bbb2d1 --- /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/) diff --git a/ru-ru/vim-ru.html.markdown b/ru-ru/vim-ru.html.markdown new file mode 100644 index 00000000..f43f99eb --- /dev/null +++ b/ru-ru/vim-ru.html.markdown @@ -0,0 +1,241 @@ +--- +category: tool +tool: vim +contributors: +    - ["RadhikaG", "https://github.com/RadhikaG"] +translators: +    - ["Anton Slukovskiy", "https://github.com/slukovskiy"] +filename: LearnVim-ru.txt +lang: ru-ru +--- + +[Vim](http://www.vim.org) +(Vi IMproved) это клон полулярного текстового редактора для Unix. Он разработан +с целью повышения скорости и продуктивности и повсеместно используется в  +большинство Юникс-подобных систем. В нем имеется множество клавиатурных  +сочетаний для быстрой навигации к определенным точкам в файле и быстрого  +редактирования. + +## Основы навигации в vim + +``` +    vim <filename>   # Открыть <filename> в vim +    :q               # Выйти из vim +    :w               # Сохранить текущий файл +    :wq              # Сохранить и выйти +    :q!              # Выйти из vim не сохраняя файл + +    :x               # Сохранить файл и выйти из vim, короткая версия :wq + +    u                # Отмена последней команды +    CTRL+R           # Отмена отмены + +    h                # Переместить курсор на один символ влево +    j                # Переместить курсор на один символ вниз +    k                # Переместить курсор на один символ вверх +    l                # Переместить курсор на один символ вправо + +    # Перемещение по строке + +    0                # Переместить курсор к началу строки +    $                # Переместить курсор к концу строки +    ^                # Переместить курсор к первому непустому символу в строке + +    # Поиск в тексте + +    /<word>          # Подсветить все вхождения <word>  в тексте после курсора +    ?<word>          # Подсветить все вхождения <word>  в тексте до курсора +    n                # Передвигает курсор к следующему вхождения искомого слова +    N                # Передвигает курсор к предыдущему вхождения искомого слова + +    :%s/foo/bar/g    # Меняет «foo» на «bar» во всем файле +    :s/foo/bar/g     # Меняет «foo» на «bar» на текущей строке + +    # Переходы к символу + +    f<character>     # Перенести курсор к <character> +    t<character>     # Перенести курсор вперед и остановиться прямо +                     # перед <character> + +    # Например, +    f<               # Перести курсор и остановиться на < +    t<               # Перенсти курсор и остановиться прямо перед < +     +    # Перемещение по словам + +    w                # Переместиться вперед на одно слово +    b                # Перенеститься назад на одно слово +    e                # Перейти к концу текущего слова + +    # Другие команды для передвижения по тексту + +    gg               # Перейти к началу файла +    G                # Перейти к концу файла +    :NUM             # Перейти к строке под номером NUM  +                     # (NUM может быть любым числом) +    H                # Переместить курсор к верхнему краю экрана +    M                # Переместить курсор к середине экрана +    L                # Переместить курсор к нижнему краю экрана +``` + +## Режимы: + +Vim основывается на концепте **режимов**. + +Командный режим - vim запускается в этом режиме по-умолчанию, используется для  +навигации и ввода команд. +Режим ввода - используется для внесения изменений в файле. +Визуальный режим - используется для подсветки текста и выполнения операций над ним. +Режим командной строки - используется для ввода команд в нижнем углу экрана после символа «:». + +``` +    i                # Переводит vim в режим вставки перед позицией курсора +    a                # Переводит vim в режим вставки после позиции курсора +    v                # Переводит vim в визуальный режим +    :                # Переводит vim в режим командной строки +    <esc>            # Выходит из любого режима в котором вы находитесь  +                     # в командный режим + +    # Копирование и вставка текста + +    y                # Скопировать выделенное +    yy               # Скопировать текущую строку +    d                # Удалить выделенное +    dd               # Удалить текущую строку +    p                # Вставить скопированный текст после текущей позиции курсора +    P                # Вставить скопированный текст перед текущей позицией курсора +    x                # Удалить символ под текущей позицией курсора +``` + +## «Грамматика» vim + +Vim можно рассматривать как набор команд в формате «Глагол-Модификатор-Существительное», где: + +Глагол - ваше действие. +Модификатор - то как вы его выполняете. +Существительное - объект над которым вы его выполняете. + +Несколько важных пример «Глаголов», «Модификаторов», и «Существительных»: + +``` +    # «Глаголы» +  +    d                # Удалить +    c                # Изменить +    y                # Скопировать +    v                # Визуально выделить + +    # «Модификаторы» + +    i                # Внутри +    a                # Снаружи +    NUM              # Число +    f                # Ищет что-то и останавливается на нем +    t                # Ищет что-то и останавливается перед ним +    /                # Ищет строку после курсора +    ?                # Ищет строку перед курсором + +    # «Существительные» + +    w                # Слово +    s                # Предложение +    p                # Параграф +    b                # Блок +     +    # Образцы «предложений» или команд + +    d2w              # Удалить 2 слова +    cis              # Изменить объемлющее предложение +    yip              # Скопировать объемлющий параграф +    ct<              # Изменяет текст от курсора до следующей открывающей скобки +    d$               # Удалить все от положения курсора до конца строки +``` + +## Некоторые сокращения и хитрости + +        <!--TODO: Add more!--> +``` +    >                # Сдвинуть выделенное на один отступ вправо +    <                # Сдвинуть выделенное на один отступ влево +    :earlier 15m     # Возвращает документ к состоянию в котором он был  +                     # 15 минут назад +    :later 15m       # Отменяет предыдущую команду +    ddp              # Меняет позиции последовательных строк, сначала dd затем p +    .                # Повторяет предыдущее действие +``` + +## Макросы + +Макросы это просто записываемые действия. +Во время записи макросы запоминают **все** действия и команды до тех пор пока  +запись не будет остановлена.При вызове макрос применяет ту же самую последовательность  +действий и команд на выделенном тексте. + +``` +    qa               # Начать запись макроса под именем «a» +    q                # Закончить запись +    @a               # Выполнить макрос  +``` + +### Настройка ~/.vimrc + +Файл .vimrc может использоваться для настройки Vim при запуске. + +Вот пример файла ~/.vimrc: + +``` +" Пример ~/.vimrc +" 2015.10  + +" Отключает совместимость со старым vi +set nocompatible + +" Определяет тип файла по его имени для разрешения автоматических отступов и т. д. +filetype indent plugin on + +" Включает подсветку синтаксиса +syntax on + +" Улучшенное автодополнение команд  +set wildmenu + +" Использовать поиск не чувствительный к регистру  +" за исключением использования заглавный букв +set ignorecase +set smartcase + +" Копирует отступы с текущей строки при добавлении новой +set autoindent + +" Показывать номера строк +set number + +" Настройки отступов, изменяйте по собственному вкусу + +" Количество видимых пробелов на один символ табуляции +set tabstop=4 + +" Количество пробелов в символе табуляции при редактировании +set softtabstop=4 + +" Количество пробелов в отступе при использовании операций >> и <<  +set shiftwidth=4 + +" Конвертировать символы табуляции в пробелы +set expandtab + +" Включить умную табуляцию и пробелы для отступов и выравнивания +set smarttab +``` + +### Ссылки + +[Vim | Home (EN)](http://www.vim.org/index.php) + +`$ vimtutor` + +[A vim Tutorial and Primer (EN)](https://danielmiessler.com/study/vim/) + +[What are the dark corners of Vim your mom never told you about? (Stack Overflow thread) (EN)](http://stackoverflow.com/questions/726894/what-are-the-dark-corners-of-vim-your-mom-never-told-you-about) + +[Arch Linux Wiki](https://wiki.archlinux.org/index.php/Vim_%28%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9%29) diff --git a/ru-ru/xml-ru.html.markdown b/ru-ru/xml-ru.html.markdown index b0096b75..bf3f22b0 100644 --- a/ru-ru/xml-ru.html.markdown +++ b/ru-ru/xml-ru.html.markdown @@ -128,3 +128,18 @@ XML-документ, который следует описанию докум    </book>  </bookstore>  ``` + +## DTD совместимость и определение XML Schema(схем/структуры) +  +Поддержка DTDs является повсеместным, потому что это довольно старая технология. К сожалению, современные функции XML как пространств имен(namespaces) не поддерживаются DTDs. Определения XML-схемы (XSDs) предназначены для замены DTDs которая в свою очередь предназначена для определения грамматики XML-документа. + +## Ресурсы + +* [Валидатор XML (ссылка на английском языке)](http://www.xmlvalidation.com) + +## Для будущего прочтения + +* [XML Schema Definitions Tutorial (ссылка на английском языке)](http://www.w3schools.com/schema/) +* [DTD руководство (ссылка на английском языке)](http://www.w3schools.com/xml/xml_dtd_intro.asp) +* [XML руководство (ссылка на английском языке)](http://www.w3schools.com/xml/default.asp) +* [использование XPath запросов для парсинга XML (ссылка на английском языке)](http://www.w3schools.com/xml/xml_xpath.asp) | 
