やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

Rustのエラー処理

 panic!(), Result(Ok<T>,Err<E>)の2種類。

成果物

参考

エラー処理

 エラー処理は以下の2種類ある。

エラー処理 動作
panic!() 強制終了
Result<Ok<T>, Err<E>> match式で分岐

panic!()

panic!("Error!");

 強制終了する。なお、以下でバックトレース一覧できる。

$ RUST_BACKTRACE=1 cargo run
$ RUST_BACKTRACE=1 rustc main.rs

Result<Ok<T>, Err<E>>

enum Result<T, E> {
    Ok(T),
    Err(E),
}

matchによる分岐

use std::fs::File;
fn main() {
    let f = File::open("hello.txt");
    let f = match f {
        Ok(file) => file,
        Err(error) => panic!("ファイルオープンに失敗しました。: {:?}", error), 
    };
}

マッチガードによるエラー種別の分岐

use std::fs::File;
use std::io::ErrorKind;
fn main() {
    let f = File::open("hello.txt");
    let f = match f {
        Ok(file) => file,
        Err(ref error) if error.kind() == ErrorKind::NotFound => {
            match File::create("hello.txt") {
                Ok(fc) => fc,
                Err(e) => panic!("ファイル作成に失敗しました: {:?}", e),
            }
        },
        Err(error) => panic!("ファイルオープンに失敗しました。: {:?}", error), 
    };
}

パニックの短縮

use std::fs::File;
fn main() {
    let f = File::open("hello.txt").unwrap();
}
use std::fs::File;
fn main() {
    let f = File::open("hello.txt").expect("Failed to open hello.txt");
}

エラー委譲(?演算子

 Before。

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

fn read_username_from_file() -> Result<String, io::Error> {
    let f = File::open("hello.txt");

    let mut f = match f {
        Ok(file) => file,
        Err(e) => return Err(e),
    };

    let mut s = String::new();

    match f.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(e) => Err(e),
    }
}

 After。

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

fn read_username_from_file() -> Result<String, io::Error> {
    let mut f = File::open("hello.txt")?;
    let mut s = String::new();
    f.read_to_string(&mut s)?;
    Ok(s)
}

 ?演算子Resultを返す関数にしか使えない。

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux

前回まで