Go だと、errors.New, fmt.Errorf で、簡単にエラーオブジェクトを作れる。
Rust のエラー処理のサンプルをいろいろ見てみたが、panic で終わらせるものが多いが、panic を使った時点で関数の汎用性がほとんどなくなってしまう。
エラーを返す場合、ほとんどの記事では自前のエラー型を作らせているが、手間がかかりすぎる。簡略化するクレートとしては、 anyhow 、thiserror などがよく紹介されているが1、 errors.New , fmt.Errorf に比べると、それすら大仰すぎる。
さらにずぼらなエラー処理を模索すると、無いこともないようで、次のような方法が見受けられた。
Result<…,String>
のように文字列型をエラーにしてしまうResult<…,Box<dyn std::error:Error>>
を使う
前者の場合、同じ関数内で ?
演算子が使えなくなってしまうため、後者を取ると、
- 既存のエラーオブジェクトは、そのまま
?
で return 値にできる(同じ trait なので) - errors.New, fmt.Errorf 的な簡易エラーは
return Err(Box::from("…"))
で作成
という形になる。これで、拙作の sponge のmain関数を書き直してみた。
fn mains() -> Result<(), Box<dyn std::error::Error>> { let mut args = std::env::args().skip(1); let original = match args.next() { Some(original) => original, None => return Err(Box::from("filename is not specified")), }; sponge(&original)?; Ok(()) } fn main() { if let Err(err) = mains() { eprintln!("{}", err); std::process::exit(1); } }
よしよし