Rust на примерах — страница 22 из 65

#![feature(never_type)]


fn main() {

let x: ! = panic!("Этот вызов никогда не вернёт управление.");

println!("вы никогда не увидете эту строку!");

}

Хотя это может показаться абстрактным понятием, на самом деле это очень полезно и может пригодится. Главное преимущество этого типа в том, что его можно привести к любому другому типу и поэтому используется в местах, где требуется точный тип, например в ветвях match. Это позволяет нам писать такой код:

fn main() {

fn sum_odd_numbers(up_to: u32) -> u32 {

let mut acc = 0;

for i in 0..up_to {

// Обратите внимание, что возвращаемый тип этого выражения match должен быть u32

// потому что такой тип в переменной "addition" .

let addition: u32 = match i%2 == 1 {

// Переменная "i" типа u32, что совершенно нормально.

true => i,

// С другой стороны выражение "continue" не возвращает

// u32, но это тоже нормально, потому что это тип не возвращающий управление,

// не нарушает требования к типу выражения match.

false => continue,

};

acc += addition;

}

acc

}

println!("Сумма нечётных чисел до 9 (исключая): {}", sum_odd_numbers(9));

}

Это также возвращаемый тип функций, которые содержат вечный цикл (например, loop {}), как сетевые серверы или функции, завершающие процесс (например, exit()).

Модули

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

Модуль - это набор элементов, таких как: функции, структуры, типажи, блоки реализации (impl) и даже другие модули.

Видимость

По умолчанию, элементы модуля являются приватными, но это можно изменить добавив модификатор pub. Только публичные элементы модуля могут быть доступны за пределами его области видимости.

// Модуль по имени `my_mod`

mod my_mod {

// Все элементы модуля по умолчанию являются приватными.

fn private_function() {

println!("вызвана `my_mod::private_function()`");

}

// Используем модификатор `pub`, чтобы сделать элемент публичным.

pub fn function() {

println!("вызвана `my_mod::function()`");

}

// Приватные элементы модуля доступны другим элементам

// данного модуля.

pub fn indirect_access() {

print!("вызвана `my_mod::indirect_access()`, которая\n> ");

private_function();

}

// Модули так же могут быть вложенными

pub mod nested {

pub fn function() {

println!("вызвана `my_mod::nested::function()`");

}

#[allow(dead_code)]

fn private_function() {

println!("вызвана `my_mod::nested::private_function()`");

}

// Функции объявленные с использованием синтаксиса `pub(in path)` будет видна

// только в пределах заданного пути.

// `path` должен быть родительским или наследуемым модулем

pub(in my_mod) fn public_function_in_my_mod() {

print!("вызвана `my_mod::nested::public_function_in_my_mod()`, которая\n > ");

public_function_in_nested()

}

// Функции объявленные с использованием синтаксиса `pub(self)` будет видна

// только в текущем модуле

pub(self) fn public_function_in_nested() {

println!("вызвана `my_mod::nested::public_function_in_nested");

}

// Функции объявленные с использованием синтаксиса `pub(super)` будет видна

// только в родительском модуле

pub(super) fn public_function_in_super_mod() {

println!("вызвана my_mod::nested::public_function_in_super_mod");

}

}

pub fn call_public_function_in_my_mod() {

print!("вызвана `my_mod::call_public_funcion_in_my_mod()`, которая\n> ");

nested::public_function_in_my_mod();

print!("> ");

nested::public_function_in_super_mod();

}

// pub(crate) сделает функцию видимой для всего текущего контейнера

pub(crate) fn public_function_in_crate() {

println!("called `my_mod::public_function_in_crate()");

}

// Вложенные модули подчиняются тем же правилам видимости

mod private_nested {

#[allow(dead_code)]

pub fn function() {

println!("вызвана `my_mod::private_nested::function()`");

}

}

}

fn function() {

println!("вызвана `function()`");

}

fn main() {

// Модули позволяют устранить противоречия между элементами,

// которые имеют одинаковые названия.

function();

my_mod::function();

// Публичные элементы, включая те, что находятся во вложенном модуле,

// доступны извне родительского модуля

my_mod::indirect_access();

my_mod::nested::function();

my_mod::call_public_function_in_my_mod();

// pub(crate) элементы можно вызвать от везде в этом же пакете

my_mod::public_function_in_crate();

// pub(in path) элементы могут вызываться только для указанного модуля

// Ошибка! функция `public_function_in_my_mod` приватная

//my_mod::nested::public_function_in_my_mod();

// TODO ^ Попробуйте раскомментировать эту строку

// Приватные элементы модуля не доступны напрямую,

// даже если вложенный модуль является публичным:

// Ошибка! функция `private_function` приватная

//my_mod::private_function();

// ЗАДАНИЕ ^ Попробуйте раскомментировать эту строку

// Ошибка! функция `private_function` приватная

//my_modmy::nested::private_function();

// ЗАДАНИЕ ^ Попробуйте раскомментировать эту строку

// Ошибка! Модуль `private_nested` является приватным

//my_mod::private_nested::function();

// ЗАДАНИЕ ^ Попробуйте раскомментировать эту строку

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה