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>
を返す関数の中でしか使えない。