Rust - современный язык программирования, нацеленный на безопасность, скорость и параллелизм. Данные цели выполняются при условии безопасной работы с памятью без использования сборщика мусора.
Rust на примерах - это набор исполняемых примеров, которые иллюстрируют различные концепции языка Rust, а так же возможности его стандартной библиотеки. Для того, чтобы подчеркнуть ещё больше из этих примеров, не забудьте установить Rust на своём компьютере и проверить официальную документацию. Если вы ранее не сталкивались с языком программирования Rust, то советую вам для начала ознакомиться с русскоязычной книгой по Rust. Кроме этого можно посмотреть исходный код этого сайта или оригинала.
Итак, давайте начнём!
• Hello World - Начните с традиционной программы Hello World.
• Примитивы - Узнайте о целых числах со знаком, целых числах без знака и других примитивах.
• Пользовательские типы - struct и enum.
• Связывание переменных - изменяемые связывания, область видимости, затенение.
• Типы - Узнаете об изменении и определении типов.
• Преобразования.
• Выражения.
• Управление потоком - if/else, for, и другие.
• Функции - Узнайте о методах, замыканиях и функциях высокого порядка.
• Модули - Организация кода с помощью модулей
• Контейнеры - Пакет - это единица компиляции в Rust. Научитесь создавать библиотеку.
• Cargo - Познакомьтесь с основными функциями официального пакетного менеджера Rust.
• Атрибуты - Атрибут - это метаданные, применяемые к какому-либо модулю, пакету или элементу.
• Обобщения - Узнайте о написании функции или типа данных, которые могут работать для нескольких типов аргументов.
• Правила областей видимости - Области видимости играют важную роль во владении, заимствовании и продолжительности жизни.
• Traits - Типаж - это набор методов, определённых для неизвестного типа: Self.
• Макросы.
• Обработка ошибок - Узнаете как в Rust обрабатывать ошибки.
• Типы стандартной библиотеки - Узнайте о некоторых пользовательских типах, предоставляемых библиотекой std.
• Разное в стандартной библиотеке - Больше пользовательских типов для обработки файлов, потоков.
• Testing - Все виды тестов в Rust.
• Unsafe.
• Совместимость.
• Meta - Документация, бенчмаркинг.
Это исходный код традиционной программы "Привет, мир!".
// Эта строка — комментарий, она будет проигнорирована компилятором
// Протестировать код можно нажав на кнопку "Run",
// которая находится в правом верхнем углу,
// или же можно использовать клавиатуру, нажав сочетание клавиш "Ctrl + Enter"
// Этот код можно редактировать не стесняясь, дерзайте!
// Всегда можно вернуть оригинальный код, нажав на кнопку "Reset". Она также находится в правом верхнем углу, но левее
// Это главная функция. С неё начинается исполнение любой программы
fn main() {
// Следующий код будет исполнен в момент, когда будет запущен исполняемый файл
// Напечатаем текст в консоли
println!("Привет, мир!");
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
println! - это макрос, который отображает текст в консоли.
Исполняемый файл может быть сгенерирован с помощью компилятора Rust — rustc.
$ rustc hello.rs
rustc создаст исполняемый файл hello, который можно будет запустить.
$ ./hello
Привет, мир!
Нажми кнопку "Run", чтобы увидеть ожидаемый результат. Затем добавь новую строку с другим макросом println!, чтобы вывод был таким:
Привет, мир!
Я программирую на языке Rust!
Каждая программа, безусловно, нуждается в комментариях и Rust предоставляет несколько способов комментирования кода:
• Обычные комментарии, которые игнорируются компилятором:
• // Однострочный комментарий. Который завершается в конце строки.
• /* Блочный комментарий, который продолжается до завершающего символа. */
• Doc комментарии, которые будут сгенерированы в HTML документацию:
• /// Генерация документации для функции.
• //! Генерация документации для модуля.
fn main() {
// This is an example of a line comment
// There are two slashes at the beginning of the line
// And nothing written inside these will be read by the compiler
// println!("Hello, world!");
// Run it. See? Now try deleting the two slashes, and run it again.
/*
* This is another type of comment, a block comment. In general,
* line comments are the recommended comment style. But
* block comments are extremely useful for temporarily disabling
* chunks of code. /* Block comments can be /* nested, */ */
* so it takes only a few keystrokes to comment out everything
* in this main() function. /*/*/* Try it yourself! */*/*/
*/
/*
Note: The previous column of `*` was entirely for style. There's
no actual need for it.
*/
// You can manipulate expressions more easily with block comments
// than with line comments. Try deleting the comment delimiters
// to change the result:
let x = 5 + /* 90 + */ 5;
println!("Is `x` 10 or 100? x = {}", x);
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Документирование библиотек
Вывод обрабатывается несколькими макросами, которые определены в std::fmt. Вот некоторые из них:
• format!: записывает форматированный текст в String.
• print!: работает аналогично с format!, но текст выводится в консоль (io::stdout).
• println!: аналогично print!, но в конце добавляется переход на новую строку.
• eprint!: аналогично format!, но текст выводится в стандартный поток ошибок (io::stderr).
• eprintln!: аналогично eprint!, но в конце добавляется переход на новую строку.
Весь текст обрабатывается аналогичным образом. Плюс данного метода в том, что корректность форматирования будет проверена на этапе компиляции программы.
fn main() {
// `{}` автоматически будет заменено на
// аргументы. Они будут преобразованы в строку.
println!("{} дней", 31);
// Без суффиксов, 31 является i32. Можно изменить тип 31,
// используя суффикс.
// Существует множество способов работы с форматированным выводом. Можно указать
// позицию для каждого аргумента.
println!("{0}, это {1}. {1}, это {0}", "Алиса", "Боб");
// Так же можно именовать аргументы.
println!("{subject} {verb} {object}",
object="ленивую собаку",
subject="быстрая коричневая лиса",
verb="прыгает через");
println!("{} из {:b} людей знают, что такое двоичный код, а остальные нет.", 1, 2);
// Можно выравнивать текст, сдвигая его на указанную ширину.
// Данный макрос отобразит в консоли
// " 1". 5 пробелов и "1".
println!("{number:>width$}", number=1, width=6);
// Можно добавить к цифрам пару нулей. Данный макрос выведет "000001".
println!("{number:>0width$}", number=1, width=6);
// Компилятор обязательно проверит, что в макрос передано правильное количество
// аргументов.
println!("Меня зовут {0}, {1} {0}", "Бонд");
// ИСПРАВЬТЕ ^ Добавьте недостающий аргумент: "Джеймс"
// Создаём структуру, которая хранит в себе `i32`. Назовём её `Structure`.
#[allow(dead_code)]
struct Structure(i32);
// Однако, пользовательские типы данных, например, как эта структура
// требуют более сложной обработки для вывода. Данный код не будет работать.
println!("Эта структура `{}` не хочет выводится на экран...", Structure(3));
// ИСПРАВЬТЕ ^ Закомментируйте эту строку.
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
std::fmt содержит в себе много типажей, которые управляют отображением текста. Базовая форма двух самых важных рассмотрена ниже:
• fmt::Debug: Использует маркер {:?}. Форматирует текст для отладочных целей.
• fmt::Display: Использует маркер {}. Форматирует текст в более элегантном,удобном для пользователя стиле.
В данном примере используется fmt::Display, потому что стандартная библиотека предоставляет реализацию для данного типа. Для отображения собственных типов потребуется больше дополнительных шагов.
Реализация типажа fmt::Display автоматически предоставляет реализацию типажа ToString, который позволяет нам конвертировать наш тип в String.
• Исправьте две ошибки в коде выше (смотрите ИСПРАВЬТЕ), чтобы код компилировался без ошибок
• Добавьте макрос println!, который выводит: Pi is roughly 3.142 с помощью управления количеством знаков после запятой. Для выполнения данного задания создайте переменную, которая будет хранить в себе значение числа Пи: let pi = 3.141592. (Подсказка: вам необходимо ознакомиться с документацией по std::fmt, чтобы узнать, как отобразить в консоли только часть знаков после запятой).
std::fmt, макросы, struct, и trait
Все типы, которые будут использовать типажи форматирования std::fmt требуют их реализации для возможности печати. Автоматическая реализация предоставлена только для типов из стандартной библиотеки (std). Все остальные типы должны иметь собственную реализацию.
C помощью типажа fmt::Debug это сделать очень просто. Все типы могут выводить (автоматически создавать, derive) реализацию fmt::Debug. Сделать подобное с fmt::Display невозможно, он должен быть реализован вручную.
#![allow(unused)]
fn main() {
// Эта структура не может быть напечатана с помощью `fmt::Display`
// или с помощью `fmt::Debug`
struct UnPrintable(i32);
// Атрибут `derive` автоматически реализует
// необходимые методы, чтобы была возможность
// печатать данную `структуру` с помощью `fmt::Debug`.
#[derive(Debug)]
struct DebugPrintable(i32);
}
Все типы в стандартной библиотеке (std) могут быть напечатаны с {:?}:
// Вывод и реализация `fmt::Debug` для `Structure`.
// `Structure` - это структура, которая содержит в себе один `i32`.
#[derive(Debug)]
struct Structure(i32);
// Добавим структуру `Structure` в структуру `Deep`.
// Реализуем для `Deep` возможность вывода с помощью fmt::Debug`.
#[derive(Debug)]
struct Deep(Structure);
fn main() {
// Вывод с помощью `{:?}` аналогичен `{}`.
println!("{:?} месяцев в году.", 12);
println!("{1:?} {0:?} - это имя {actor:?}.",
"Слэйтер",
"Кристиан",
actor="актёра");
// `Structure` теперь можно напечатать!
println!("Теперь {:?} будет выведена на экран!", Structure(3));
// Проблема с `выводом (derive)`, в том, что у нас не будет контроля
// над тем, как будет выглядеть результат.
// Что если мы хотим напечатать просто `7`?
println!("А теперь напечатаем {:?}", Deep(Structure(7)));
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Так что fmt:: Debug определённо делает это для печати, но жертвует некоторыми изящество. Rust также обеспечивает "красивую печать" с помощью {:#?}.
#[derive(Debug)]
struct Person<'a> {
name: &'a str,
age: u8
}
fn main() {
let name = "Peter";
let age = 27;
let peter = Person { name, age };
// Pretty print
println!("{:#?}", peter);
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה