? 演算子ではエラー型の自動変換ができる。

これにより複数種のエラーをまとめて扱える。

基本

E1From<E2> を実装している場合、つまり E1E2 と変換できる場合、? 演算子は Result<T, E1>Result<T, E2> と自動変換できる。

サンプル

以下は From の API ドキュメントからの抜粋


use std::fs;
use std::io;
use std::num;

enum CliError {
    IoError(io::Error),
    ParseError(num::ParseIntError),
}

impl From<io::Error> for CliError {
    fn from(error: io::Error) -> Self {
        CliError::IoError(error)
    }
}

impl From<num::ParseIntError> for CliError {
    fn from(error: num::ParseIntError) -> Self {
        CliError::ParseError(error)
    }
}

fn open_and_parse_file(file_name: &str) -> Result<i32, CliError> {
    let mut contents = fs::read_to_string(&file_name)?;
    let num: i32 = contents.trim().parse()?;
    Ok(num)
}

クレート紹介

anyhow は柔軟なエラー処理を可能にするクレートである。

このクレートの型 anyhow::Error はトレイト std::err::Error を実装する型からの変換を受け付けている。これにより、エラー専用の型として設計された型ならどれでも、anyhow のエラーとしてまとめて扱えるようになっている。