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
Displayrepresentation of an error type should be lowercase without trailing punctuation, and typically concise.
「小文字で、句読点をつけない」とのこと。
次のような例も示されているので、途中に単語として大文字が混じるのは良さそうですね。
- "unexpected end of file"
- "provided string was not
trueorfalse"- "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 を試しても良さそう (普段は使っていない) 。
追記: 次回『 Rust の Error の downcast で Box<dyn Error> からエラーを取り出す』を書きました。
Discussion