0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Goのwrap結局何がうれしいんや

Posted at

#goのwrap結局何が嬉しいのか

先日go1.13から実装されたwrapについての記事を書いたのですが,自分で例とかも書きながら、これって本当にうれしいんか?というか何が嬉しいんやろという疑問がありました。そこで、自分の社内の先輩に嬉しいところを聞いてみたところ、なぁぁぁぁるほどぉぉぉというお答えを頂けたので、自分なりにまとめて書いてみようと思います。

#嬉しいところ

僕が前の記事でエラーをラップすると嬉しいこととして、下位の関数で発生したえらーを上位の関数にシンプルな形でエラーを返せるというような説明をしました。これは本当に嬉しいことでは無かったです。書きながら自分でも疑問だったのですが、結局unwrapするんだしwrapする必要あるのか?ということです。
本当に嬉しかった事としては、もし、下位の関数で定義したエラーを上位の関数に返してしまうと、上位の関数が下位の関数に依存してしまう事になります。ここで、エラーを上位の関数が定義したエラーでwrapする事で依存を防げるのですね。これが本当は嬉しい事だったわけです。

#実装してみる

 具体的にどうやって、実装するんや、という話です。
例えば、databaseとの接続部で出たエラーをcontroller層に返す時を考えます。まず、database側でこんなエラーを実装したとします

dababase.go
type DataBaseError struct {
  err error
}

func (e dataBaseError)Error() string {
 return e.err.Error()
}

これをwrapせずにコントローラー層に返してしまうと、controller層が外側のdatabase層のDataBaseErrorを知ることになり、依存の方向が逆向きになってしまいます。(dao→controllerの依存のみ許します)この DataBaseError をWrapしてcontroller層に返すことで、 *fmt.WrrapError 型として返るのでcontroller層はDataBaseErrorのことを知らずにdaoからのエラーを扱えるようになります。
。。。。( ^ω^ )
ということを考えながら、自分で言ってて、これUnWrapできんやん、むしろ、AsとかIsとかをcontroller層でやろうとしたら、 errors.Is(err, dao.DataBaseError) とか書くことになって、結局依存解消できんやんとか自分で突っ込んでしまいました。どうしたもんか

#というわけで、自分なりにもうちょっと考えてみる
色々と調べてみて、考えてみたのですが、確かに、unwrapしない限りは下位の層で定義したエラーを渡さなくて済むのですが、一番嬉しいこととしては自分で定義しエラーを扱う時に、複雑なものなどが必要になったら、wrapしてあげると綺麗なわかりやすい形で渡せることなのかな、という結論に行き着きました。また、そう言った使い方をしている例が多かったように思います。(大半はラップの仕方だけで、嬉しいことはあまり書いてなかった、、)。
もしかしたら、うまく実装できればunwrapしても依存しない形を作れるのかなーとか思ったので、あったらコメントとかしていただけると嬉しいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?