Оператор ?

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

Оператор ? после значения Result указывает, что если функция возвращает объект Result, который представляет константу Ok, то возвращается значение из константы Ok. Однако если значение Result предоставляет константу Err, то Err будет возвращаться из всей вызывающей функции, в которой получен объект Result.

Рассмотрим следующий пример:

fn main() ->Result<(), String>{
 
    let tom = create_person("Tom", 36)?;
    println!("Name: {}  Age: {}", tom.name, tom.age);
	Ok(())
}
 
struct Person{ name: String, age:u8}
 
fn create_person(username: &str, userage: u8) -> Result<Person, String>{
     
    if userage < 110{
        let new_person = Person{name: String::from(username), age: userage };
        Result::Ok(new_person)
    }
    else { 
        Result::Err(String::from("Некорректный возраст. Возраст должен быть меньше 110")) 
    }
}

Функция create_person() возвращает объект Result. Поэтому при ее вызове в main к ней можно применить оператор ?:

let tom = create_person("Tom", 36)?;

То есть здесь нам не надо применять никаких конструкций match или дополнительных методов типа unwrap() или expect(), чтобы получить требуемый объект Person.

Однако в этом случае функция, которая вызывает функцию create_person() также должна возвращать объект Result. То есть в данном случае функция main() должна определять в качестве возвращаемого типа тип Result. Но функция main является особой функцией, которая может возращать только тип (). Этот тип еще называется unit type и аналогичен типу void в других языках программирования.

Чтобы выйти из ситуации первый параметр типа в Result<T, E> (параметр T) представляет тип (), а второй - тип ошибки (то есть тип String):

fn main() ->Result<(), String>{

Кроме того, в конце функция возвращает константу Ok(), в которую передается ():

Ok(())

При этом возвращать отдельно константу Err() не надо, поскольку это делает автоматически оператор ?

Стоит отметить, что в реальности оператор ? можно применять к функциям, которые возвращают объекты типов Result или Option или других типов, которые реализуют трейт std::ops::Try.

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