Error トレイトの定義を確認してみた
前々回は Result<T, E>
について書き、前回は Result<T, E>
のよく使うメソッドについて書きました。
Rust の Result<T, E>
の T
や E
は任意の型を使用できます。ただ E
は多くの場合 Error
トレイトを実装した型を指定します。
……というわけで今回は Rust の標準ライブラリにある Error
トレイトについて書いてみます。
ちなみに、 Rust API ガイドラインの項目に Result<T, E>
の E
のようなエラー型は Error
トレイトを実装すべきと明記してあります。
Error
トレイトの定義
改めて。 std::error::Error
トレイトはエラー値に期待される基本的な性質を表現します。例えば Result<T, E>
の E
の型の値です……的なことがドキュメントの 1 行目から書いてあります。
Error
トレイトの定義はだいたいこんな感じです。
trait Error: Debug + Display {
fn source(&self) -> Option<&(dyn Error + 'static)>;
// deprecated since 1.42.0
fn description(&self) -> &str;
// deprecated since 1.33.0
fn cause(&self) -> Option<&dyn Error>;
// nightly-only
fn provide<'a>(&'a self, request: &mut Request<'a>);
}
4 つあるメソッドのうち、 3 つは deprecated と nightly-only です。 stable を想定すれば「 Debug と Display を実装していて source
メソッドがある」程度のものですね。
無視するつもりのものをざっと見ると……。
description
は Display
や to_string
で代替されています。
cause
は source
で代替されています。
provide
はあまりよく分かっていないですが、エラー報告用のコンテキストデータを提供するためのものっぽいですね。 Backtrace のコード例が示されています。
Debug
と Display
Error
のスーパートレイトとして指定されている Debug
と Display
ですが、これらも標準のトレイトです。
Debug
は format!
で {:?}
と指定したときの文字列形式、 Display
は format!
で {}
と指定したときの文字列形式ですね。前者は開発者向け (デバッグ用途) 、後者はユーザー向けの出力ですね。
description
の代替であることから、エラーを説明するような文字列に to_string
で変換されることが想定されていそうです。
Display
の例
さきほども紹介した Rust API ガイドラインの項目に Error
の Display
の形式についても記載があります。
The error message given by the
Display
representation of an error type should be lowercase without trailing punctuation, and typically concise.
「小文字で、句読点をつけない」とのこと。
次のような例も示されているので、途中に単語として大文字が混じるのは良さそうですね。
- "unexpected end of file"
- "provided string was not
true
orfalse
"- "invalid IP address syntax"
- "second time provided was later than self"
- "invalid UTF-8 sequence of {} bytes from index {}"
- "environment variable was not valid unicode: {:?}"
Error::source
Error::source
は cause
を代替していることから分かるように、エラーの原因になった、より低レベルなエラーを返すものです。
なければなくて (None
) で良いと。 前にも書いた Option
ですね。
次回予告
thiserror
crate を使いながら実装します (たぶん) 。 downcast
を試しても良さそう (普段は使っていない) 。
Discussion