Храните ровно одно из состояний — успех или ошибка — во внутреннем enum. Struct-обёртка предоставляет заданные ok/err и consuming unwrap-методы.
Создание собственного типа Result
Храните ровно одно из состояний — успех или ошибка — во внутреннем 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.