Skip to content
Update rust error authored by umaumax's avatar umaumax
......@@ -101,6 +101,38 @@ pub enum MyError {
}
```
## anyhow::Resultの使い方
### anyhow::Result<>は普通の構造体をエラーとして持つ場合は`?`を利用できる
ResultのEがErrorトレイトを満たす単なる構造体については`?`を利用するだけで良い
`Result<(), Box<dyn std::error::Error>>`に対して`?`とするとエラーとなるので、
`Result<(), Box<dyn std::error::Error + Send + Sync>>`へ変更して、`hoge().map_err(|e| anyhow::anyhow!(e))?;`とすればOK
そのまま返すと`trait `Sized` is not implemented`となるので、間に変換を挟む必要がある
(このテクニックはlifetime境界が含まれるエラー型から新規の`'static`なエラー型を生成する場合にも使える)
参考: [Explicit constructor from Box<dyn Error + Send + Sync> · Issue #83 · dtolnay/anyhow]( https://github.com/dtolnay/anyhow/issues/83 )
[Error in anyhow - Rust]( https://docs.rs/anyhow/1.0.44/anyhow/struct.Error.html#impl-From%3CError%3E )`Send``Sync`なしの`impl From<Error> for Box<dyn StdError + 'static>`も存在するが、
ソースコードを見るとラップされているだけであり、内部では`impl From<Error> for Box<dyn StdError + Send + Sync + 'static>`を呼びだす
`new`から生成する場合にも
[error.rs - source]( https://docs.rs/anyhow/1.0.34/src/anyhow/error.rs.html#25 )
にある通り、
`anyhow::Error``failure::Error`のように`From<_: std::error::Error + Send + Sync + 'static>`を満たすので、様々なエラー型をまとめて扱える
ここで、Errorトレイトを満たす単なる構造体の場合は、通常プリミティブ型のみで構成されているので、
自然に`Send``Sync`の条件を満たしているので、特に意識することなく、`From`トレイトによって、自動変換されていることがわかる
ただし、
[rust - Why doesn't Box<dyn Error> implement Error? - Stack Overflow]( https://stackoverflow.com/questions/65151237/why-doesnt-boxdyn-error-implement-error )
にある通り、下記のように変換しようとすると`Sized`が実装されておらず変換できない
``` rust
let box_error: Box<dyn std::error::Error + Send + Sync + 'static> = todo!();
let anyhow_error = anyhow::Error::from(&box_error);
```
## ライブラリを利用しない場合の汎用的なエラー型
`Result<(), Box<dyn std::error::Error>`を関数の返り値に利用すると良い
......@@ -117,14 +149,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
> 戻り値の型は`Result<T, Box<dyn std::error::Error + Send + Sync + 'static>>`とした方がベターとのことです.
### デバッグのために適当なエラーを利用したい
## デバッグのために適当なエラーを利用したい
[Error in std::io - Rust]( https://doc.rust-lang.org/std/io/struct.Error.html )
``` rust
let custom_error = std::io::Error::new(std::io::ErrorKind::Other, "oh no!");
```
### 1つの関数に複数の種類のエラーが入り交じる場合の返り値のResultの型はどうする?
## 1つの関数に複数の種類のエラーが入り交じる場合の返り値のResultの型はどうする?
1. `Result<(),Box<dyn std::error::Error>>`
例えば、ライフタイムを有する構造体をSendした際のエラー型にはライフタイムが含まれており、Boxは利用できない
......
......