Обработка ошибок

Макрос panic!

Последнее обновление: 04.05.2021

В Rust все ошибки делятся на две категории: recoverable (обрабатываемые) и unrecoverable (необрабатываемые). При возникновении обрабатываемой ошибки, (например, отсутствие запрошенного файла) можно сообщить о проблеме пользователю и вернуться к нормальной работе программы (если файл отсуствует - то можно обработать - создать новый файл). Необрабатываемые ошибки (например, обращение к несуществующему элементу вектора) нередко являются показателями наличия в программе багов, в такой ситуации сложно как-то обработать ситуацию.

Для обработки обрабатываемых ошибок Rust предоставляет специальный тип Result<T, E>, а для обработки ситуации, когда возникает необрабатываемая ошибка - макрос panic!. Хотя оба средства также могут сочетаться в рамках обработки одной ошибки.

Макрос panic!

Для обработки ситуаций, когда возникает необрабатываемая ошибка, применяется макрос panic!. При его выполнении программа выводит на консоль сообщение об ошибке, очищает стек и завершает выполнение программы.

Ряд потенциальных необрабатываемых ошибок Rust может отловить на этапе компиляции, например, возьмем ситуацию, когда мы обращаемся к несуществующему элементу массива:

fn main() {
	let numbers = [1, 2, 3, 4];
    println!("{}", numbers[10]);
}

В данном случае в массиве numbers 4 элемента, соответственно элемента с индексом 10, который мы пытаемся вывести на консоль, в массиве не существует. И при компиляции мы получим ошибку:

Uncoverable errors in Rust

Однако изменим тип данных с массива на вектор:

fn main() {
	let numbers = vec![1, 2, 3, 4];
    println!("{}", numbers[10]);
}

В векторе также 4 элемента, а элемента с индексом 10 не существует. Однако вектор может увеличиваться, и компилятор не сможет отловить возникновение ошибки. Поэтому компиляция завершится успешно, однако при выполнении программы мы все равно столкнемся с ошибкой:

panic! in Rust

Это как раз и результат выполнения макроса panic!, которое прописано в исходном коде. В выводимом на консоль макросом сообщении мы можем увидеть прежде всего сообщение об ошибке: "index out of bounds: the len is 4 but the index is 10". Кроме того, мы можем увидеть строку кода, на которой произошла ошибка. В этом случае нам легче идентифицировать место и характер ошибки и внести соответствующие исправления.

Но мы сами можем вызывать данный макрос в различных частях программы для обработки подобных ситуаций. Например, для имитации ошибки просто применим этот макрос:

fn main() {
    panic!("непредвиденная ошибка");
}

В макрос panic! передается сообщение, которое затем будет выводиться на консоль при возникновении ошибки. Так, при выполнении этой программы мы увидим на консоли наше сообщение и краткую информацию о возникшей ошибке:

Макрос panic в Rust

Рассмотрим другой более практичный пример: у нас есть функция, которая извне получает некоторые данные. Однако эти данные могу быть некорректными. И в этом случае мы можем вызвать макрос panic:

fn main(){

	let tom = create_person("Tom", 136);
	println!("Name: {}  Age: {}", tom.name, tom.age);
}

struct Person{ name: String, age:u8}

fn create_person(username: &str, userage: u8) -> Person{
	
	if userage > 110{
		panic!("Некорректный возраст. Возраст должен быть меньше 110");
	}
	else { 
		let new_person = Person{name: String::from(username), age: userage };
		new_person
	}
}

Здесь функция create_person() получает извне имя и возраст пользователя и по ним создает объект структуры Person, который возвращается из функции. Однако если возраст некорретный (в рамках данной программы условимся, что таким является возраст выше 110), то вызывается макрос panic!, который с помощью передаваемого сообщения раскравает причину ошибки.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850