【ヒント】Goで必要ない限りinit()の使用を避ける
By JoeVu, at: 2024年9月11日11:08
Estimated Reading Time: __READING_TIME__ minutes
![[TIPS] Avoid Using init() in Go Unless Necessary](/media/filer_public_thumbnails/filer_public/ba/65/ba65941e-134e-43ec-b905-12ad67dc2502/golang_-_init_function.png__1500x900_crop_subsampling-2_upscale.png)
![[TIPS] Avoid Using init() in Go Unless Necessary](/media/filer_public_thumbnails/filer_public/ba/65/ba65941e-134e-43ec-b905-12ad67dc2502/golang_-_init_function.png__400x240_crop_subsampling-2_upscale.png)
Goにおいて不要な限りinit()
の使用を避ける
Goのinit()
関数は、main()
関数よりも前、パッケージ内の他のコードよりも前に自動的に実行される特別な関数です。便利な場合もありますが、使いすぎるとコードの追跡と保守が難しくなる可能性があります。絶対に必要な場合を除き、init()
の使用を避けるべき理由を以下に示します。
init()
が問題となる理由
-
隠れたロジック:
init()
は自動的に実行されるため、コードのメインフローからは明らかではない隠れた動作が導入される可能性があります。これは、特に大規模なプロジェクトでは、デバッグとコードの理解をより困難にする可能性があります。
-
実行順序: Goは、異なるパッケージ間での
init()
関数の実行順序を保証しません。複数のパッケージにinit()
関数がある場合、予測できない動作につながり、プログラムの推論が難しくなります。
-
複雑なテスト: 重要な設定ロジックが
init()
内に隠れている場合、テスト中にモックしたりバイパスしたりすることが困難になる可能性があります。これにより、記述と保守が困難な密結合テストにつながる可能性があります。
init()
を使用する場合
潜在的な欠点にもかかわらず、init()
には正当な使用例があります。
-
パッケージレベルの設定: パッケージが使用される前に何らかの状態または設定を初期化する必要がある場合(例:グローバルロガーの設定)、
init()
が役立ちます。ただし、この設定が不可欠であり、main()
または他の場所で処理できないことを確認してください。
-
コンポーネントの登録: プラグインやミドルウェアなど、拡張可能な機能を提供するパッケージの中には、コンポーネントを登録するために
init()
を使用するものがあります。これは許容されますが、混乱を避けるためにこの動作を明確に文書化してください。
init()
の使用例
package main
import (
"log"
"os"
)
func init() {
// グローバルロガーを設定する
log.SetOutput(os.Stdout)
log.Println("Logger initialized")
}
func main() {
log.Println("This is the main function")
}
この例では、init()
を使用して、main()
関数が実行される前にグローバルロガーを設定しています。これは有効な使用例ですが、より明確にするために、この設定をmain()
で明示的に行うことができるかどうかを検討してください。
さらに読む: https://www.digitalocean.com/community/tutorials/understanding-init-in-go