Как отобразить файл _err., открытый?

#rust

Вопрос:

Я пытаюсь отобразить ошибку при открытии файла, как это:

 #[derive(Debug, Clone)]
pub enum BitstreamCreationError {
    FileNotFound(String),
    Unknown(String),
}

fn main() {
    let file = std::fs::File::open("my/path").map_err(|e| match e {
        Err(std::io::Error{..}) if e.kind() == std::io::ErrorKind::NotFound => BitstreamCreationError::FileNotFound,
        _ => BitstreamCreationError::Unknown(format!("{:?}",e)),
    });
}
 

Игровая площадка

так что я могу вернуться с ? сообщением в случае ошибки. Однако я понимаю это:

Ошибка:

 error[E0308]: `match` arms have incompatible types
  --> /home/dev/orwell/liborwell/src/core/bitstream_rtsp_client.rs:81:18
   |
78 |           let file = File::open(url.clone()).map_err(|e| match e {
   |  ________________________________________________________-
79 | |             //e if e.kind() == std::io::ErrorKind::NotFound => BitstreamCreationError::FileNotFound,
80 | |             Err(std::io::Error{..}) if e.kind() == std::io::ErrorKind::NotFound => BitstreamCreationError::FileNotFound,
   | |                                                                                    ------------------------------------ this is found to be of type `fn(std::string::String) -> BitstreamCreationError {BitstreamCreationError::FileNotFound}`
81 | |             _ => BitstreamCreationError::Unknown(format!("{:?}",e)),
   | |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn item, found enum `BitstreamCreationError`
82 | |         });
   | |_________- `match` arms have incompatible types
 

Почему в нем говорится, что тип первого варианта совпадения такой fn(std::string::String) -> BitstreamCreationError {BitstreamCreationError::FileNotFound} ? Для меня это не имеет никакого смысла.

Ответ №1:

В вашем коде есть две проблемы. Один из них заключается в том, что map_err при закрытии передается экземпляр ошибки , а не ошибка, завернутая в a Result , поэтому вы должны соответствовать std::io::Error { .. } , а не включаться Err(...) . Другое заключается в том, что оба ваших варианта перечисления требуют строки, поэтому вы должны строить FileNotFound с BitstreamCreationError::FileNotFound(<some string>) помощью . Если вы опустите как строку, так и круглые скобки, это выглядит так, как будто вы ссылаетесь на функцию BitstreamCreationError::FileNotFound , которая строит a BitstreamCreationError из строки, и именно поэтому сообщение об ошибке ссылается на fn(String) -> BitstreamCreationError .

Исправленный код может выглядеть следующим образом:

 let file = std::fs::File::open("my/path").map_err(|e| match e {
    std::io::Error { .. } if e.kind() == std::io::ErrorKind::NotFound => {
        BitstreamCreationError::FileNotFound(format!("{:?}", e))
    }
    _ => BitstreamCreationError::Unknown(format!("{:?}", e)),
});