【Rust】エラーハンドリングの基本

実行した時にエラーになりうる関数はResultを返す。
Ok(File), Err(Error)など

use std::fs::File;

fn main() {
    let result = File::open("file.txt");
    match result {
        Ok(file) => {
            println!("ファイルのオープンに成功しました!");
        }
        Err(error) => {
            println!("ファイルのオープンに失敗しました!");
        }
    }
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.70s
Running `target/debug/app`
ファイルのオープンに失敗しました!

関数化すると

use std::fs::File;

#[derive(Debug)]
struct MyError {
    message: String,
}

fn main() {
    let result = open_file();
    println!("{:?}", result);
}

fn open_file() -> Result<File, MyError> {
    let result = File::open("file.txt");
    match result {
        Ok(file) => {
            return Ok(file);
        }
        Err(error) => {
            let error = MyError{ message: "ファイルのオープンに失敗しました!".to_string()};
            return Err(error);
        }
    }
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.30s
Running `target/debug/app`
Err(MyError { message: “ファイルのオープンに失敗しました!” })

### エラーが発生した時、発生したエラーをそのまま返す

fn main() {
    let result = open_file();
    println!("{:?}", result);
}

fn open_file() -> Result<File, std::io::Error> {
    let result = File::open("file.txt");
    match result {
        Ok(file) => {
            return Ok(file);
        }
        Err(error) => {
            return Err(error);
        }
    }
}

“?”とすれば、その時点でエラーを返す。下記の方が簡略して書ける。

fn main() {
    let result = open_file();
    println!("{:?}", result);
}

fn open_file() -> Result<(), std::io::Error> {
    let result = File::open("file.txt");
    let file = result?;
    Ok(())
}

File::open(SCHEDULE_FILE).unwrap()のunwrap()はエラーだたった時、エラー内容を表示してそのまま終了してしまう。
Result<(), std::io::Error> と書いた場合は、エラーだったときに、終了せずにエラーを返す。