Rust, anyhowのマクロ(anyhow!, bail!, ensure!)の使い方
Rustでanyhowのマクロ(anyhow!, bail!, ensure!)を使うと、関数から簡単にエラーを返すことができる。任意の条件で単発のエラーを返すのに便利。
ここではそれぞれのマクロの使い方について説明する。
anyhowの基本的な使い方については以下の記事を参照。
- 関連記事: Rust, anyhowによる基本的なエラー処理
本記事のサンプルコードにおけるanyhowのバージョンは以下の通り。
anyhow = "1.0"
use宣言は以下の通り。
use anyhow::{anyhow, bail, ensure, Result};
anyhow!: anyhow::Errorを生成
anyhow!はanyhow::Errorを生成する。
引数は文字列で、format!のようにプレースホルダー{}を含められる。もちろん{}なしの文字列でもよい。
fn with_anyhow(i: i32) -> Result<i32> {
if i < 10 {
return Err(anyhow!("Value must be at least 10, got {}", i));
};
Ok(i)
}
上の例のようにreturnで返す場合、その関数の返り値の型はResult<T, anyhow::Error>とする。use anyhow::Result;としておくと、Result<T>と書ける。
実行結果は以下の通り。
assert_eq!(with_anyhow(10).unwrap(), 10);
assert_eq!(
with_anyhow(9).unwrap_err().to_string(),
"Value must be at least 10, got 9"
);
ここでは、簡単のため、返り値に対してunwrapやunwrap_errで値やエラーを取り出して確認しているが、実際のプログラムでは適切なエラー処理を行えばよい。以降の例も同じ。
bail!: anyhow::Errorをreturn
bail!はanyhow::Errorをreturnする。
return Err(anyhow!($args...)と等価。
fn with_bail(i: i32) -> Result<i32> {
if i < 10 {
bail!("Value must be at least 10, got {}", i);
};
Ok(i)
}
assert_eq!(with_bail(10).unwrap(), 10);
assert_eq!(
with_bail(9).unwrap_err().to_string(),
"Value must be at least 10, got 9"
);
anyhow::Errorをreturnするので、Result<T, anyhow::Error>を返す関数の中でしか使えない。
ensure!: 条件を満たさないときにanyhow::Errorをreturn
ensure!は第一引数に条件を指定する。その条件を満たさない(falseである)ときにanyhow::Errorをreturnする。
if !$cond { return Err(anyhow!($args...)); }と等価。条件に否定の!が付いていることに注意。
fn with_ensure(i: i32) -> Result<i32> {
ensure!(i >= 10, "Value must be at least 10, got {}", i);
Ok(i)
}
assert_eq!(with_ensure(10).unwrap(), 10);
assert_eq!(
with_ensure(9).unwrap_err().to_string(),
"Value must be at least 10, got 9"
);
条件を満たす場合はスルーし、満たさない場合にエラーを返す。パニックを発生させるのではなくエラーを返すassert!のようなもの。
bail!と同様にanyhow::Errorをreturnするので、Result<T, anyhow::Error>を返す関数の中でしか使えない。