2020/03/08

[golang]エラーの返し方

C言語の時はあまり悩まなかった・・・いや、どうするかは悩むけど言語的には悩まなかったエラーの返し方。
golangの場合は、だいたいerrorsというものを使っているようだ。

 

Pythonもそうだけど、戻り値を簡単に複数返すことができるというのは楽ですな。
私の場合、C言語ではboolを戻り値にして「成功かエラー」だけにすることが多い。
多いのだが、あまり考えたくないというのと、組み込みだと「エラーが起きる=リセットするしかない or バグ」ということがほとんどだったので、戻り値を用意してスタックを使ってしまうくらいだったらvoidでいいや、みたいな気持ちだったからだ。
ほら、エラーが起きたことを知らせるにしても、LEDの点滅とかブザー鳴動だし。

しかし、最近は組み込みじゃないプログラムを書くことが増え、「エラーをユーザに見せる」という技がいるようになってきた。そうするとboolではとても足りず、「intにするか・・・でも戻り値の変更はつらいので引数増やすか・・・でもそれも・・・」とさらに悩むということになってしまっている。

 

その点、複数の戻り値を同時に返すことができるし、戻り値の2番目にerrorsを返しがち、というルールもあるようなので、それに載っかるのが無難だろう。

ただ・・・個人的には暗黙のルールってのがどうも苦手で。
プロジェクトごととか個人のルールはあってしかるべきだが、言語でのルールは仕様に含めてしまってもいいのでは・・・。

いや、そうしたらしたで「なんでここまで縛られるんじゃー」って思うのは間違いないな。


それはともかく、errorsの使い方も調べる。

errors - GoDoc
https://godoc.org/github.com/pkg/errors

発生時はNew()かErrorf()で新規に作るか、伝えられたerrorsに情報を付加して返すかだろう。
WithMessage()とWrap()は同じもののような気がするが、実装はどうなんだろう?

01: func Wrap(err error, message string) error {
02:     if err == nil {
03:         return nil
04:     }
05:     err = &withMessage{
06:         cause: err,
07:         msg:   message,
08:     }
09:     return &withStack{
10:         err,
11:         callers(),
12:     }
13: }
  
01: func WithMessage(err error, message string) error {
02:     if err == nil {
03:         return nil
04:     }
05:     return &withMessage{
06:         cause: err,
07:         msg:   message,
08:     }
09: }
  

Wrap()は、WithMessage()+コールスタック、というところだろうか。

 

普段ならコードを書いて検証するところなのだが、今日は気分が乗らない・・・。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。