Как правильно использовать метод Option :: ok_or ()? - PullRequest
0 голосов
/ 05 января 2019

Я пытаюсь понять, как использовать оператор вопросительного знака для обработки ошибок в Rust. У меня есть этот код:

fn main() -> Result<(), &'static str> {
    let foo: i32 = Some("1")
        .ok_or(Err("error 1"))?
        .parse()
        .or(Err("error 2"))?;
    Ok(())
}

Этот код не может быть скомпилирован по какой-либо причине:

error[E0277]: the trait bound `&str: std::convert::From<std::result::Result<_, &str>>` is not satisfied
 --> src/main.rs:2:20
  |
2 |       let foo: i32 = Some("1")
  |  ____________________^
3 | |         .ok_or(Err("error 1"))?
  | |_______________________________^ the trait `std::convert::From<std::result::Result<_, &str>>` is not implemented for `&str`
  |
  = note: required by `std::convert::From::from`

В Rust book есть пример использования оператора вопросительного знака:

use std::io;
use std::io::Read;
use std::fs::File;

fn read_username_from_file() -> Result<String, io::Error> {
    let mut s = String::new();

    File::open("hello.txt")?.read_to_string(&mut s)?;

    Ok(s)
}

По моему мнению, это не сильно отличается от моего примера в смысле обработки ошибок. Я не вижу причины, по которой мой код неверен. Если черта From должна быть реализована для всех видов Result, почему код из книги Rust работает нормально?

1 Ответ

0 голосов
/ 05 января 2019

В отличие от or, ok_or занимает E, а не полное Result<T, E> (потому что не будет ничего делать, если передано Ok). Просто передайте строку ошибки напрямую:

fn main() -> Result<(), &'static str> {
   let foo: i32 = Some("1")
       .ok_or("error 1")?
       .parse()
       .or(Err("error 2"))?;
    Ok(())
}

Причина, по которой в сообщении об ошибке упоминается черта From, заключается в том, что ? неявно использует From для преобразования типа ошибки выражения в тип ошибки возвращаемого значения. Если бы это сработало, .ok_or(Err("error 1")) вернул бы значение Result<&'static str, Result<_, &'static str>> (_ может быть почти любым, поскольку Err не указывает). Оператор ? пытается найти реализацию From, которая преобразует Result<_, &'static str> (тип ошибки выражения) в &'static str (тип ошибки возвращаемого значения). Поскольку такой реализации From не существует, компилятор выдает ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...