Создание собственного типа Result

Храните ровно одно из состояний — успех или ошибка — во внутреннем enum. Struct-обёртка предоставляет заданные ok/err и consuming unwrap-методы.

Короткий ответ

Что ответить на собеседовании

Храните ровно одно из состояний — успех или ошибка — во внутреннем enum. Struct-обёртка предоставляет заданные ok/err и consuming unwrap-методы.

Подробный разбор

Ответ с пояснениями

Условие

В задаче требуется разработать собственный тип Result, который будет использоваться для передачи результата выполнения функции вместе с информацией об ошибке. Реализуйте структуру Result<T, E>, где T – тип данных в случае успеха, а E – тип ошибки. Предусмотрите методы для создания успешного результата и результата с ошибкой, а также методы для проверки состояния и получения вложенных значений.

Требования:

  • Определите обобщённую структуру Result<T, E>.
  • Реализуйте конструкторы ok(value: T) -> Result<T, E> и err(error: E) -> Result<T, E>.
  • Добавьте методы is_ok() -> bool, is_err() -> bool.
  • Реализуйте методы unwrap() -> T (выбрасывает паника при ошибке) и unwrap_err() -> E (выбрасывает паника при успехе).
  • По желанию можно добавить методы map, map_err и прочие удобные функции.

Пример использования (можно изменить названия переменных, но код оставьте без изменений):

let success: Result<i32, &str> = Result::ok(42);
let failure: Result<i32, &str> = Result::err("error occurred");

assert!(success.is_ok());
assert!(!failure.is_ok());

let value = success.unwrap();
let err_msg = failure.unwrap_err();

Задача подходит для оценки умения работать с обобщениями, паттернами обработки ошибок и базовых принципов проектирования API.

Ответ

Храните ровно одно из состояний — успех или ошибка — во внутреннем enum. Struct-обёртка предоставляет заданные ok/err и consuming unwrap-методы.

enum State<T, E> { Ok(T), Err(E) }
struct Result<T, E> { state: State<T, E> }

impl<T, E> Result<T, E> {
    fn ok(value: T) -> Self { Self { state: State::Ok(value) } }
    fn err(error: E) -> Self { Self { state: State::Err(error) } }
    fn is_ok(&self) -> bool { matches!(&self.state, State::Ok(_)) }
    fn is_err(&self) -> bool { !self.is_ok() }
    fn unwrap(self) -> T {
        match self.state {
            State::Ok(value) => value,
            State::Err(_) => panic!("unwrap on error"),
        }
    }
    fn unwrap_err(self) -> E {
        match self.state {
            State::Err(error) => error,
            State::Ok(_) => panic!("unwrap_err on success"),
        }
    }
}

Это отдельный учебный Result, затеняющий стандартный одноимённый тип. Два Optional-поля хуже: они допускают невозможные состояния «оба заполнены»/«оба пусты». Unwrap забирает self и переносит payload без требования Copy. В прикладном коде ожидаемые ошибки обычно обрабатывают pattern matching, не panic.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее