Язык программирования Rust: объектно-ориентированное программирование
Содержание:
1. История и установка;
2. Утилиты, документация, идеология и синтаксис;
3. Переменные, указатели, массивы и функции;
4.Объектно-ориентированное программирование (Вы читаете данный раздел);
5. Исключения и общие выводы.
Подход к объектно-ориентированному программированию в Rust похож на таковой в языке Go. Как таковых классов нет, но можно «привязывать» функции специального вида к любому типу и они автоматически становятся методами этого типа:
Самая оригинальная особенность синтаксиса языка Rust - это конструкция match. Ее корни восходят к конструкции switch в Си, но в Rust она превратилась чуть ли не в центральный элемент языка. В простейшем виде match похожа на своего прародителя:
Символ «_» используется как заполнитель для произвольного значения. В теле match происходит так называемая «деструктуризация» - присвоение локальных имен полям типов данных:
Такое поведение выглядит необычно, но оно очень удобно и лаконично описывает сложные логические ветвления.
Давайте с вами более подробно рассмотрим продвинутые возможности данного языка программирования.
В Rust имеются обобщенные функции и записи, но их поведение отличается от привычного в С++:
Но не компилируется:
Информации по обобщенным функциям в документации очень мало, но очевидно, что шаблоны не подставляются на этапе компиляции, как в С++ (превращаясь в конкретные типы), а обрабатываются иначе. Честно говоря, мне так и не удалось до конца понять, почему не компилируется приведенный выше фрагмент и как правильно использовать обобщенные функции.
В Rust также нет шаблонного метапрограммирования и возможности выполнения кода на этапе компиляции, которые доступны с C++ и D.
Язык Rust создавался с прицелом на простую реализацию многопоточности и коммуникации потоков. Порождение новых потоков рекомендовано выполнять в функциональном стиле с помощью блока do. Тело этого блока становится замыканием, которое будет выполняться в отдельном потоке:
Коммуникация между потоками осуществляется с помощью портов и каналов. Канал - это отсылающий конец коммуникационного потока, а порт - принимающий. Каналы «параметризуются» типом данных, который они могут передавать:
В языке предусмотрены также двунаправленные каналы коммуникации. В целом реализация многопоточности практически полностью «слизана» с языка Go.
Создали уникальное приложение на языке программирования Rust и планируете вывести его в массы? В таком случае, спешу сообщить Вам, что в вашем начинании Вам поможет тизерная сеть (http://good-teasers.ru), которая познакомит с вашим продуктом тысячи заинтересованных пользователей!
Более детальную информацию Вы найдете на good-teasers.ru.
1. История и установка;
2. Утилиты, документация, идеология и синтаксис;
3. Переменные, указатели, массивы и функции;
4.
5. Исключения и общие выводы.
Объектно-ориентированное программирование
Подход к объектно-ориентированному программированию в Rust похож на таковой в языке Go. Как таковых классов нет, но можно «привязывать» функции специального вида к любому типу и они автоматически становятся методами этого типа:
// Объявляем запись с двумя полями struct A {
x: float,
y: float
}
// Добавляем к этой записи «реализацию» impl A {
// Метод, складывающий поля записи fn add(&self) -> float{
return self.x + self.y
}
}
let a = A {x:1.0,y:2.0}; // Создаем запись
io::println(fmt!("%f",a.add())); // Вызываем «привязанный» к ней метод
x: float,
y: float
}
// Добавляем к этой записи «реализацию» impl A {
// Метод, складывающий поля записи fn add(&self) -> float{
return self.x + self.y
}
}
let a = A {x:1.0,y:2.0}; // Создаем запись
io::println(fmt!("%f",a.add())); // Вызываем «привязанный» к ней метод
Конструкция match
Самая оригинальная особенность синтаксиса языка Rust - это конструкция match. Ее корни восходят к конструкции switch в Си, но в Rust она превратилась чуть ли не в центральный элемент языка. В простейшем виде match похожа на своего прародителя:
match my_number {
0 => io::println("HOЛЬ"),
1 | 2 => io::println("один или два"),
3..10 => io::println("интервал от 3 до 10"),
_ => io::println("что-то другое")
}
0 => io::println("HOЛЬ"),
1 | 2 => io::println("один или два"),
3..10 => io::println("интервал от 3 до 10"),
_ => io::println("что-то другое")
}
Символ «_» используется как заполнитель для произвольного значения. В теле match происходит так называемая «деструктуризация» - присвоение локальных имен полям типов данных:
// Функция принимает кортеж из двух чисел fn angle(vector: (float, float)) -> float { let pi = float::consts::pi; match vector {
// первый элемент кортежа должен быть равен 0
// второй элемент кортежа заносится в y
// если он меньше нуля, то этот пункт срабатывает,
// а иначе выполнение идет дальше и срабатывает следующий (0f, y) if y 1.5 * pi, (0f, y) => 0.5 * pi,
// Элементы кортежа заносятся в x и y и используются (x, y) => float::atan(y / x)
}
}
// первый элемент кортежа должен быть равен 0
// второй элемент кортежа заносится в y
// если он меньше нуля, то этот пункт срабатывает,
// а иначе выполнение идет дальше и срабатывает следующий (0f, y) if y 1.5 * pi, (0f, y) => 0.5 * pi,
// Элементы кортежа заносятся в x и y и используются (x, y) => float::atan(y / x)
}
}
Такое поведение выглядит необычно, но оно очень удобно и лаконично описывает сложные логические ветвления.
Продвинутые возможности языка
Давайте с вами более подробно рассмотрим продвинутые возможности данного языка программирования.
Обобщенное программирование
В Rust имеются обобщенные функции и записи, но их поведение отличается от привычного в С++:
// Обобщенная функция для сложения двух чисел...
// Вроде бы выглядит элементарно: fn g (a: T, b: T) -> T {
return a+b;
}
// Вроде бы выглядит элементарно: fn g
return a+b;
}
Но не компилируется:
error: binary operation + cannot be applied to type ‘'a’
Информации по обобщенным функциям в документации очень мало, но очевидно, что шаблоны не подставляются на этапе компиляции, как в С++ (превращаясь в конкретные типы), а обрабатываются иначе. Честно говоря, мне так и не удалось до конца понять, почему не компилируется приведенный выше фрагмент и как правильно использовать обобщенные функции.
В Rust также нет шаблонного метапрограммирования и возможности выполнения кода на этапе компиляции, которые доступны с C++ и D.
Многопоточность
Язык Rust создавался с прицелом на простую реализацию многопоточности и коммуникации потоков. Порождение новых потоков рекомендовано выполнять в функциональном стиле с помощью блока do. Тело этого блока становится замыканием, которое будет выполняться в отдельном потоке:
use core::task::spawn;
// Все, что находится в теле блока do, становится телом
// замыкания, которое вызывается в отдельном потоке for int::range(0, 20) |child_task_number| {
do spawn {
print(fmt!("Привет, я отдельный поток с номером %dn", child_task_number));
}
}
// Все, что находится в теле блока do, становится телом
// замыкания, которое вызывается в отдельном потоке for int::range(0, 20) |child_task_number| {
do spawn {
print(fmt!("Привет, я отдельный поток с номером %dn", child_task_number));
}
}
Коммуникация между потоками осуществляется с помощью портов и каналов. Канал - это отсылающий конец коммуникационного потока, а порт - принимающий. Каналы «параметризуются» типом данных, который они могут передавать:
use core::task::spawn;
use core::comm::{stream, Port, Chan};
// Создаем порт и канал для передачи целых чисел
let (port, chan): (Port , Chan ) = stream();
do spawn || {
// В новом потоке выполняем какую-то длительную операцию
let result = some_expensive_computation();
// Отсылаем результат
chan.send(result);
}
// В основном потоке тоже делаем что-то длительное
some_other_expensive_computation();
// Принимаем результат
let result = port.recv();
use core::comm::{stream, Port, Chan};
// Создаем порт и канал для передачи целых чисел
let (port, chan): (Port
do spawn || {
// В новом потоке выполняем какую-то длительную операцию
let result = some_expensive_computation();
// Отсылаем результат
chan.send(result);
}
// В основном потоке тоже делаем что-то длительное
some_other_expensive_computation();
// Принимаем результат
let result = port.recv();
В языке предусмотрены также двунаправленные каналы коммуникации. В целом реализация многопоточности практически полностью «слизана» с языка Go.
Создали уникальное приложение на языке программирования Rust и планируете вывести его в массы? В таком случае, спешу сообщить Вам, что в вашем начинании Вам поможет тизерная сеть (http://good-teasers.ru), которая познакомит с вашим продуктом тысячи заинтересованных пользователей!
Более детальную информацию Вы найдете на good-teasers.ru.