diff options
author | hyphz <drmoose94@gmail.com> | 2017-07-18 17:56:42 +0100 |
---|---|---|
committer | hyphz <drmoose94@gmail.com> | 2017-07-18 17:56:42 +0100 |
commit | 5ab5cb9800822d607be2c6ac943377811db98158 (patch) | |
tree | 3c804707822744c20da1de54ff60fc8c3197781b /ru-ru | |
parent | 62102d02992f83b3a1fb745a39f36332dd4435b7 (diff) | |
parent | 6e7c5c793327f4a63b13e555894597915ca91fda (diff) |
Merge remote-tracking branch 'adambard/master'
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 ![Альтернативный текст для изображения](http://imgur.com/myimage.jpg "Подсказка") +``` +Изображения тоже могут быть оформлены, как сноски. -<!-- Изображения тоже могут быть оформлены, как сноски: --> - -![Альтернативный текст][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) |