🔍
Go1.23以降でのerrors.Is:ネスト不要でエラーハンドリングをシンプルに
Goのエラーハンドリングにおける errors.Is の変化について、特にバージョン1.22から1.23への移行で注目すべきポイントがあります。この記事では、その違いと、コードのリファクタリング方法について説明します。💡
errors.Is
の挙動の違い 🧐
変更点: Go 1.23以降では、 errors.Is
の内部に nil
チェックが含まれるようになりました。これにより、以下のように err != nil
を明示的にチェックするコードがよく見られますが…
if err != nil {
if errors.Is(err, targetErr) {
// targetErr に一致した処理
}
}
実はこれ、Go 1.23以降ではネストしなくても同じ結果が得られるようになりました。具体的には、 errors.Is
内で nil
のチェックが行われるので、次のように書くことが可能です。
if errors.Is(err, targetErr) {
// targetErr に一致した処理
}
if err != nil {
// その他の処理
}
なぜこれが効率的なのか?⚡
Go 1.23以降、 errors.Is
内で nil
のチェックが自動で行われるため、重複して err != nil
のチェックを行う必要がなくなりました。これにより、コードがシンプルで読みやすくなります。
実際の動作を確認してみよう!📝
次に、簡単なコードでこの動作を確認しましょう。
コード例 1: Go 1.22 のスタイル
package main
import (
"errors"
"fmt"
)
var targetErr = errors.New("target error")
func checkError(err error) {
if err != nil {
if errors.Is(err, targetErr) {
fmt.Println("Matched target error!")
} else {
fmt.Println("Different error")
}
} else {
fmt.Println("No error occurred.")
}
}
func main() {
err := fmt.Errorf("wrapped: %w", targetErr)
checkError(err)
}
コード例 2: Go 1.23 以降のスタイル
package main
import (
"errors"
"fmt"
)
var targetErr = errors.New("target error")
func checkError(err error) {
if errors.Is(err, targetErr) {
fmt.Println("Matched target error!")
} else if err != nil {
fmt.Println("Different error")
} else {
fmt.Println("No error occurred.")
}
}
func main() {
err := fmt.Errorf("wrapped: %w", targetErr)
checkError(err)
}
結論 💡
Go 1.23以降では、 errors.Is
が内部で nil
チェックを行うため、無駄なネストを避けてスッキリしたコードを書けるようになりました。コードの可読性とシンプルさは、プロジェクトのメンテナンス性を向上させる重要な要素です。ぜひ、 if err != nil
を省略する書き方を検討してみてください!
それでは、シンプルなコードライフをお楽しみください!😄
Discussion