Знак вопроса со своим сбоем в Rust
Когда перевод из чужого сбоя уже написан, в теле функции можно не разворачивать исход вручную. Знак вопроса после выражения, которое может дать сбой, сам превращает его во вторую ветку вашего типа и сразу выходит из функции.
Так код читается по шагам успеха: сначала разбор, потом работа с числом, без вложенных проверок на каждой строке. Главное, чтобы тип сбоя в сигнатуре совпадал с тем, куда переводят библиотечные сбои.
Запишем загрузку числа из текста:
#[derive(Debug)]
struct PathError {
path: String,
}
impl std::fmt::Display for PathError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "bad path {}", self.path)
}
}
impl std::error::Error for PathError {}
impl From<std::num::ParseIntError> for PathError {
fn from(_: std::num::ParseIntError) -> Self {
PathError {
path: String::from("input"),
}
}
}
fn load(text: &str) -> Result<i32, PathError> {
let n: i32 = text.parse()?;
Ok(n)
}
fn main() {
match load("24") {
Ok(n) => println!("{}", n),
Err(e) => println!("{}", e),
}
}
На экране 24. После знака вопроса сбой
разбора стал PathError, потому что блок
перевода уже был в типе.
При плохом тексте функция вернет сбой без дополнительных веток внутри:
#[derive(Debug)]
struct PathError {
path: String,
}
impl std::fmt::Display for PathError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "bad path {}", self.path)
}
}
impl std::error::Error for PathError {}
impl From<std::num::ParseIntError> for PathError {
fn from(_: std::num::ParseIntError) -> Self {
PathError {
path: String::from("input"),
}
}
}
fn load(text: &str) -> Result<i32, PathError> {
let n: i32 = text.parse()?;
Ok(n)
}
fn main() {
match load("no") {
Ok(n) => println!("{}", n),
Err(e) => println!("{}", e),
}
}
Дан следующий код:
struct SizeError {
note: String,
}
impl std::fmt::Display for SizeError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "size {}", self.note)
}
}
impl std::error::Error for SizeError {}
Добавьте перевод из ParseIntError с
note "parse" и функцию, которая
читает i32 из ссылки на строку с
короткой записью сбоя. Проверьте удачный и
неудачный текст в main.
Дан следующий код:
struct PairError {
part: String,
}
Соберите полный тип сбоя, перевод из сбоя разбора и функцию с двумя шагами разбора в одном теле, каждый с короткой записью. Верните сумму чисел или сбой.
Дан следующий код:
struct IdError {
id: String,
}
Оформите цепочку: разбор i32, затем
проверка, что число больше нуля, иначе
IdError с id "range". Для
разбора используйте короткую запись сбоя
после перевода из ParseIntError.