summaryrefslogtreecommitdiffhomepage
path: root/ru-ru
diff options
context:
space:
mode:
Diffstat (limited to 'ru-ru')
-rw-r--r--ru-ru/binary-search-ru.html.markdown64
-rw-r--r--ru-ru/c-ru.html.markdown9
-rw-r--r--ru-ru/javascript-ru.html.markdown1
-rw-r--r--ru-ru/php-ru.html.markdown35
-rw-r--r--ru-ru/qt-ru.html.markdown158
-rw-r--r--ru-ru/swift-ru.html.markdown264
6 files changed, 447 insertions, 84 deletions
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
index 5e967181..ab4be57e 100644
--- a/ru-ru/c-ru.html.markdown
+++ b/ru-ru/c-ru.html.markdown
@@ -145,7 +145,7 @@ int main() {
f1 / f2; // => 0.5, плюс-минус погрешность потому что,
// цифры с плавающей точкой вычисляются неточно!
- // Модуль
+ // Остаток от деления
11 % 3; // => 2
// Операции сравнения вам уже знакомы, но в Си нет булевого типа.
@@ -286,7 +286,7 @@ int main() {
// => Напечатает "8, 4" в 64 битной системе
// Для того, чтобы получить значение по адресу, напечатайте * перед именем.
- // Да, использование * при объявлении указателя и получении значения по адресу
+ // Да, * используется при объявлении указателя и для получении значения по адресу
// немного запутано, но вы привыкнете.
printf("%d\n", *px); // => Напечаатет 0, значение перемененной x
@@ -305,8 +305,9 @@ int main() {
// Объявление указателя на int с адресом массива.
int* x_ptr = x_array;
// x_ptr сейчас указывает на первый элемент массива (со значением 20).
- // Это рабоатет, потому что имя массива возвращает указатель на первый элемент.
- // Например, когда массив передаётся в функцию или назначается указателю, он
+ // Это работает, потому что при обращении к имени массива возвращается
+ // указатель на первый элемент.
+ // Например, когда массив передаётся в функцию или присваивается указателю, он
// невявно преобразуется в указатель.
// Исключения: когда массив является аргументом для оператор '&':
int arr[10];
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/php-ru.html.markdown b/ru-ru/php-ru.html.markdown
index 42c4d360..b5feb105 100644
--- a/ru-ru/php-ru.html.markdown
+++ b/ru-ru/php-ru.html.markdown
@@ -58,7 +58,8 @@ $int1 = 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;
@@ -86,8 +87,9 @@ $dbl_quotes = "This is a $sgl_quotes."; // => 'This is a $String.'
// Специальные (escape) символы работают только в двойных кавычках
$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 может использоваться для
@@ -140,11 +142,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]);
/********************************
* Вывод
@@ -184,6 +195,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 )
/********************************
* Логические выражения
@@ -204,12 +219,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
@@ -265,6 +289,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';
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"
```