Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Представлення ?

Іноді ми просто хочемо простоти unwrap без можливості panic. Досі unwrap змушував нас вкладатися дедалі глибше, тоді як насправді ми хотіли просто отримати змінну назовні. Саме для цього і призначений ?.

Після виявлення Err є дві допустимі дії:

  1. panic!, чого ми вже вирішили, якщо можливо, уникати
  2. return, тому що Err означає, що його не можна обробити

? — це майже1 точно еквівалент unwrap, який виконує return замість panic при Err. Подивімося, як можна спростити попередній приклад, що використовував комбінатори:

use std::num::ParseIntError;

fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    let first_number = first_number_str.parse::<i32>()?;
    let second_number = second_number_str.parse::<i32>()?;

    Ok(first_number * second_number)
}

fn print(result: Result<i32, ParseIntError>) {
    match result {
        Ok(n)  => println!("n is {}", n),
        Err(e) => println!("Error: {}", e),
    }
}

fn main() {
    print(multiply("10", "2"));
    print(multiply("t", "2"));
}

Макрос try!

До появи ? та сама функціональність досягалася за допомогою макроса try!. Оператор ? тепер рекомендовано використовувати, але ви все ще можете зустріти try!, коли переглядаєте старіший код. Така сама функція multiply із попереднього прикладу виглядала б так із використанням try!:

// Щоб скомпілювати й запустити цей приклад без помилок, використовуючи Cargo, змініть значення
// поля `edition` у розділі `[package]` файлу `Cargo.toml` на "2015".

use std::num::ParseIntError;

fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    let first_number = try!(first_number_str.parse::<i32>());
    let second_number = try!(second_number_str.parse::<i32>());

    Ok(first_number * second_number)
}

fn print(result: Result<i32, ParseIntError>) {
    match result {
        Ok(n)  => println!("n is {}", n),
        Err(e) => println!("Error: {}", e),
    }
}

fn main() {
    print(multiply("10", "2"));
    print(multiply("t", "2"));
}

  1. Див. повернення до ? для докладнішої інформації.