Skip to content
GitLab
Menu
Why GitLab
Pricing
Contact Sales
Explore
Why GitLab
Pricing
Contact Sales
Explore
Sign in
Get free trial
Changes
Page history
Update rust error
authored
Oct 16, 2021
by
umaumax
Show whitespace changes
Inline
Side-by-side
rust/rust-error.md
View page @
66d8bbe9
...
...
@@ -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は利用できない
...
...
...
...