Menu
Coddy logo textTech

Оператор вопросительного знака '?'

Часть раздела Логика и управление потоком путешествия по Rust на Coddy. Урок 46 из 66.

При работе с функциями, возвращающими Result, часто требуется обрабатывать ошибки: либо обрабатывать их локально, либо передавать их вызывающей функции. Rust предоставляет элегантный оператор для этого распространённого шаблона: оператор вопросительного знака ?.

Оператор ? предоставляет удобный способ распространять ошибки без написания громоздких операторов match. Когда вы помещаете ? после Result, он автоматически распаковывает значение Ok или немедленно возвращает управление из текущей function с помощью Err:

fn parse_and_double(s: &str) -> Result<i32, std::num::ParseIntError> {
    let number = s.parse::<i32>()?; // Если парсинг не удался, вернуть ошибку
    Ok(number * 2) // Если успешно, удвоить число
}

Это эквивалентно записи полной инструкции match, но гораздо короче. Если s.parse::<i32>() возвращает Ok, оператор ? извлекает значение и присваивает его number. Если возвращается Err, оператор ? немедленно возвращает эту ошибку из всей function.

Обратите внимание на синтаксис ::<i32>. Он называется turbofish и сообщает Rust, в какой тип следует преобразовать строку при разборе. Функция возвращает Result<i32, std::num::ParseIntError>, где i32 — тип успешного результата, а std::num::ParseIntError — тип ошибки, возвращаемый, когда parsing fails.

Оператор ? можно использовать только в функциях, которые возвращают Result (или Option), поскольку он должен иметь возможность вернуть ошибку.

challenge icon

Задание

Легко

Вы получите два входных значения. Первое входное значение — это строка, которую следует преобразовать в целое число, а второе входное значение — другая строка, которую также следует преобразовать в целое число. Создайте функцию с именем add_numbers, которая принимает два строковых среза в качестве параметров и возвращает Result<i32, std::num::ParseIntError>. Внутри функции используйте оператор ?, чтобы преобразовать обе строки, и верните их сумму, обёрнутую в Ok. Вызовите функцию с двумя входными значениями и обработайте результат с помощью match.

Требования:

  • Прочитайте первое входное значение (первое число в виде строки) и удалите пробелы
  • Прочитайте второе входное значение (второе число в виде строки) и удалите пробелы
  • Создайте функцию add_numbers, которая принимает два параметра &str и возвращает Result<i32, std::num::ParseIntError>
  • Внутри функции преобразуйте первую строку в i32 с помощью оператора ?
  • Преобразуйте вторую строку в i32 с помощью оператора ?
  • Верните Ok(sum), где sum — это сумма обоих преобразованных чисел
  • Вызовите функцию с двумя входными строками
  • Используйте выражение match для обработки Result
  • В ветви Ok(value) выведите: Sum: [value]
  • В ветви Err(_) выведите: Parsing error

Ввод:

  • Первая строка: строка, представляющая число (например, 15)
  • Вторая строка: строка, представляющая другое число (например, 27)

Вывод:

  • Если обе строки являются допустимыми числами: Sum: [result]
  • Если одну из строк невозможно преобразовать: Parsing error

Попробуйте сами

use std::io;

// TODO: Создайте функцию add_numbers здесь
// Она должна принимать два параметра &str и возвращать Result&lt;i32, std::num::ParseIntError&gt;


fn main() {
    // Прочитать первый ввод
    let mut input1 = String::new();
    io::stdin().read_line(&mut input1).expect("Failed to read line");
    let input1 = input1.trim();
    
    // Прочитать второй ввод
    let mut input2 = String::new();
    io::stdin().read_line(&mut input2).expect("Failed to read line");
    let input2 = input2.trim();
    
    // TODO: Вызовите add_numbers с input1 и input2
    // TODO: Используйте match для обработки Result
    // Выведите "Sum: [value]" для Ok(value)
    // Print "Parsing error" for Err(_)
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Логика и управление потоком

Потренируйтесь самостоятельно: Онлайн-компилятор Rust