昨日Go言語で困ってるって話を書いたら、budougumi先生からおたよりが来ました。ありがたや!
[error型の返り値を無視してしまう問題]
この関数でerr2を返すべきなのにー、って話を書いた。
func myFunction(param string) (string, error) { err1 := check1(param)
if err1 != nil { return "", err1 } err2 := check2(param)
if err2 != nil { return "", err1 } return param }
budougumi先生からのおたよりはこちら。
`if err := check1(param); err != nil { `って書くべきですね。変数スコープかぶらないのでわざわざerr"1"とかする必要もなくなりますし。冗長になっているというのはどのへんでしょうか?同じ処理を2行で既に書いているので文字数的には";"が増えてるだけなような?
— Yoichiro Shimizu (@budougumi0617) January 22, 2019
errの宣言とnilチェックを1行で書けばエラー名もシンプルになるしスコープちゃんと考えろよ!と。確かに他のライブラリとかでこの書き方見た覚えがあるけど、あんまり理解してなかった。反省。
冗長だなーと思ったのはエラーが発生しているのにnilチェックをかけないといけない部分だったんだけど、JavaとかJavaScriptのthrow Exception
みたいな大域脱出は例外が正しくハンドリングされない可能性もある。そう考えると、error型をちゃんとハンドリングできるGo言語の方が堅牢な書き方が出来るのかも。
[適切なerrorをリターンしない問題]
とはいえ、Go言語で書いていてもerror型を無視してコーディングしてもコンパイルを通すことができてしまう。
func main() { isValid("myParam")// エラー型を受け取らなくても良い } func isValid(param string) error { if ... { return errors.New("invalid parameter") } return nil }
budougumi先生からのおたよりはこちら。
return errorを受けるのを忘れたりするのはCI回すときにerrcheckかけておくので防いでますね。https://t.co/n4LQGAyGnP
— Yoichiro Shimizu (@budougumi0617) January 22, 2019
便利そうなツール!(未導入)
来週中くらいには回せるようになりたい……ならないかな(多分このブログを読んでいるであろうCI担当メンバの方をみつめる :eyes:)。
あれ、でも普段VS Codeで拡張機能使って開発してるんだけど、errcheckデフォルトで有効になってそう……なんかうまく動かない条件とかあるのかな。はて。少し調べてみよう。
[まとめ]
budougumi先生いつもありがとうございます!!