Большая шпаргалка по Rust. 1/2

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.



Hello world!


Представляю вашему вниманию первую часть большой шпаргалки по Rust.


Обратите внимание: шпаргалка рассчитана на людей, которые хорошо знают любой современный язык программирования, а не на тех, кто только начинает кодить ;)


Также настоятельно рекомендуется хотя бы по диагонали прочитать замечательный Учебник по Rust (на русском языке).


Содержание


  • Основы
    • Комментарии и документирование кода
    • Переменные, константы и статики
    • Функции
    • Примитивные типы данных
    • Операторы
    • Потоки управления
  • Больше, чем основы
    • Векторы (vectors)
    • Структуры (structs)
    • Перечисления (enums)
    • Дженерики (generics)
    • Реализации и трейты (impls \& traits)
  • Сложная часть
    • Владение (ownership)
    • Заимствование (borrowing)
    • Времена жизни (lifetimes)

Основы


Комментарии и документирование кода


Комментарии


// Строчные комментарии
/* Блочные комментарии */

Поддерживаются вложенные блочные комментарии.


Старайтесь избегать использования блочных комментариев.


Комментарии документации (doc comments)


Команда cargo doc генерирует документацию проекта с помощью rustdoc. Для генерации документации используются док-комментарии.


Обычно мы добавляем док-комментарии в библиотечные крейты (library crates). Внутри док-комментариев можно использовать Markdown.


/// Строчные комментарии; документируют следующий элемент
/** Блочные комментарии; документируют следующий элемент */

//! Строчные комментарии; документируют вложенный элемент
/*! Блочные комментарии; документируют вложенный элемент !*/

Пример:


/// Этот модуль содержит тесты; внешний комментарий
mod tests {
    // ...
}

mod tests {
    //! Этот модуль содержит тесты; внутренний комментарий
    // ...
}

Ключевое слово mod используется для модулей. Мы обсудим это позже.


Док-атрибуты (doc attributes)


Док-атрибуты являются альтернативой док-комментариям. Мы используем их для управления rustdoc. Подробнее о док-атрибутах можно почитать здесь.


В следующем примере каждый комментарий эквивалентен соответствующему док-атрибуту:


/// Внешний комментарий
#[doc = "Внешний комментарий"]

//! Внутренний комментарий
#![doc = "Внутренний комментарий"]

Атрибут — это общие метаданные в свободной форме, которые интерпретируются в соответствии с названием, соглашением, версиями языка и компилятора. Синтаксис:


  • внешний атрибут: #[attr]
  • внутренний атрибут: #![attr]

Перед тем, как двигаться дальше...


  • Используйте //! только для написания документации крейта. Для блоков mod используйте /// снаружи блоков. Взгляните на использование док-комментариев //! и /// в популярных крейтах на crates.io. Например, взгляните на serde/src/lib.rs и rand/src/lib.rs
  • выполните команду cargo new hello_lib --lib для создания образца крейта и замените код в файле src/lib.rs на следующий:

//! Простой крейт Hello World

/// Эта функция возвращает приветствие; Hello, world!
pub fn hello() -> String {
    ("Hello, world!").to_string()
}

#[cfg(test)]
mod tests {
    use super::hello;

    #[test]
    fn test_hello() {
        assert_eq!(hello(), "Hello, world!");
    }
}

Затем выполните cargo doc --open для генерации документации и ее открытия в вашем дефолтном браузере.


Переменные, константы и статики


  • В Rust переменные по умолчанию являются иммутабельными (неизменными/неизменяемыми) (immutable), поэтому они называются привязками переменных (variable bindings). Для объявления мутируемой (изменяемой) (mutable) переменной используется ключевое слово mut.
  • Rust — это статически типизированный язык: типы данных (data types) проверяются во время компиляции. Однако это не означает, что типы всех переменных должны указываться явно. Компилятор "смотрит" на использование переменной и устанавливает для нее лучший тип. Но для констант (constants) и статики (statics) типы должны указываться явно. Типы указываются после двоеточие (:).

В следующих примерах мы используем такие типы данных, как bool, i32, i64 и f64. Мы обсудим это позже.


Переменные


Для объявления переменной используется ключевое слово let. Название (имя) переменной может быть привязано к значению или функции. Также поскольку левая часть выражения привязки является "паттерном" (pattern) мы можем привязывать несколько названий к нескольким значениям или функциям.


// Иммутабельная переменная
let a; // Объявление (declaration); без типа данных
a = 5; // Присвоение/присваивание значения (assignment)

let b: i8; // Объявление; с типом данных
b = 5;

let t = true;        // Объявление + присвоение; без типа данных
let f: bool = false; // Объявление + присвоение; с типом данных

// Несколько переменных
let (x, y) = (1, 2); // x = 1 и y = 2

// Мутабельная переменная
let mut z = 5;
z = 6;

// Значением переменной становится результат выражения
let z = { x + y }; // z = 3
// Затенение/перезапись переменной (variable shadowing) (см. ниже)
let z = {
    let x = 1;
    let y = 2;

    x + y
}; // z = 3

В Rust точка с запятой (;) в конце строки кода является обязательной (в отличие, например, от JavaScript). Отсутствие ; обычно означает возврат результата выражения.


Константы


Для определения констант используется ключевое слово const. Константы являются иммутабельными. Они живут в течение всего жизненного цикла программы, но не имеют фиксированного адреса в памяти.


// Название в стиле SCREAMING_SNAKE_CASE
// Тип указывается явно
const CONST_VAR: i32 = 5;

Статики


Ключевое слово static используется для определения объекта типа "глобальная переменная". Для каждого значения существует только один экземпляр такого объекта. Значение находится в фиксированном месте в памяти.


static STATIC_VAR: i32 = 5;

Старайтесь всегда использовать const вместо static для определения констант. Привязка места в памяти к константе требуется очень редко. Использование const позволяет выполнять такие оптимизации, как распространение константы (constant propagation) не только в вашем крейте, но также в зависимых/подчиненных крейтах.


Затенение переменных (variable shadowing)


Иногда возникает необходимость преобразовать значение переменной из одних единиц в другие для дальнейшей обработки. Rust позволяет повторно объявлять переменные с другими типами данных и/или другими настройками мутабельности. Это называется затенением.


fn main() {
    let x: f64 = -20.48; // float - число с плавающей точкой
    // Явное приведение/преобразование типа
    let x: i64 = x.floor() as i64; // int - целое число
    println!("{}", x); // -21

    let s: &str = "hello"; // &str - строковый срез
    // Неявное преобразование типа
    let s: String = s.to_uppercase(); // String - строка
    println!("{}", s) // HELLO
}

Перед тем, как двигаться дальше...


  • Для названий переменных используется стиль snake_case, а для названий констант и статик — SCREAMING_SNAKE_CASE
  • обычно константы и статики определяются в начале файла снаружи функции (после импорта модулей/объявлений use)

const PI: f64 = 3.14159265359;

fn main() {
    println!("Значение π: {}", PI);
}

Функции


Именованные функции


  • объявляются с помощью ключевого слова fn
  • при использовании аргументов, необходимо определять их типы
  • по умолчанию функции возвращают пустой кортеж (tuple) (()). Возвращаемый тип определяется после ->

Hello world


fn main() {
    println!("Hello, world!");
}

Передача аргументов


fn print_sum(a: i8, b: i8) {
    println!("Cумма: {}", a + b);
}

Возврат значения


// Без ключевого слова `return`. Возвращается только последнее выражение
fn plus_one(a: i32) -> i32 {
    a + 1
    // В конце этой строки отсутствует `;`
    // Это выражение эквивалентно `return a + 1;`
}

// С ключевым словом `return`
fn plus_two(a: i32) -> i32 {
    return a + 2;
    // Ключевое слово `return` следует использовать только для условного/раннего возврата (early return).
    // Использование `return` в последнем выражении считается плохой практикой
}

Указатели на функцию (function pointers), использование в качестве типа данных


fn main() {
    // Без объявлений типов
    let p1 = plus_one;
    let x = p1(5); // 6

    // С объявлениями типов
    let p1: fn(i32) -> i32 = plus_one;
    let x = p1(5); // 6
}

fn plus_one(a: i32) -> i32 {
    a + 1
}

Замыкания (closures)


  • Также известны как анонимные или лямбда-функции
  • типы аргументов и возвращаемого значения являются опциональными

Именованная функция без замыкания


fn main() {
  let x = 2;
  println!("{}", get_square_value(x));
}

fn get_square_value(i: i32) -> i32 {
    i * i
}

С опциональными объявлениями типов аргумента и возвращаемого значения


fn main() {
    let x = 2;
     // Аргументы передаются внутри | |, а тело выражения оборачивается в { }
    let square = |i: i32| -> i32 {
        i * i
    };
    println!("{}", square(x));
}

Без объявлений типов


fn main() {
    let x = 2;
    let square = |i| i * i; // { } являются опциональными для однострочных замыканий
    println!("{}", square(x));
}

С опциональными объявлениями типов; создание + вызов


fn main() {
    let x = 2;
    let x_square = |i: i32| -> i32 { i * i }(x); // { } являются обязательными при одновременном создании и вызове
    println!("{}", x_square);
}

Без объявлений типов; создание + вызов


fn main() {
    let x = 2;
    let x_square = |i| -> i32 { i * i }(x); // тип возвращаемого значения является обязательным
    println!("{}", x_square);
}

Примитивные типы данных


bool


true или false.


let x = true;
let y: bool = false;

char


Единичное скалярное значение Юникода.


// Кавычки должны быть одинарными
let x = 'x';
let y: char = '						
Источник: https://habr.com/ru/companies/timeweb/articles/785096/


Интересные статьи

Интересные статьи

Делимся ссылками на примеры API разных стилей, которое можно подёргать в режиме онлайн прямо на сайтах. Также к большинству ссылок есть документация.
В данной статье представлены примеры использования фикстур (fixture) для фреймворка автоматического тестирования pytest. Фикстуры представляют собой функции, которые можно использовать для решения раз...
Что-то зачастили они Последние годы, перевернувшие нашу привычную жизнь вверх дном, помимо всего остального, радуют нас яркими кометами. В 2019/2020 году окрестности Солнца посетила комета N...
Привет, Хабр! Мы продолжаем рассказывать о системе дистанционной оценки повреждений авто. В прошлой статье мы раскрыли основные принципы ее нейросетей, на которых она строится.
Отрасль IT развивается стремительно. Создаются новые технологии и знания, возникают идеи и стартапы, гиганты индустрии лидируют по капитализации в списках крупнейших компаний мира, а более традиц...