#![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();
// ЗАДАНИЕ ^ Попробуйте раскомментировать эту строку
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה