Goは、main()の開始前に初期化コードを実行するためにinit関数をサポートしています。Goプログラムを実行すると、コンパイラは各パッケージで宣言されたすべてのinit関数を変数の初期化後に自動的に呼び出します。
問題の背景: パッケージが使用される前に、一度だけ状態を準備する必要があります。
問題: initの初期化順序は、しばしば明示的でないエラーの原因になります。特にパッケージ間の依存関係が多い場合、特定のinit関数がいつ実行されるかを制御するのは困難です。
解決策:
コードの例:
package example import "fmt" var Cfg string = "default" func init() { fmt.Println("example init") Cfg = "configured" }
主な特徴:
1つのファイルに複数のinit関数を定義できますか?
はい、複数のinit関数が許可されており、宣言された順序で呼び出されます。
パッケージが間接的にインポートされる(_ "package"を介して)場合、何が起こりますか?
そのパッケージのinit関数と変数の初期化のみが実行されます。
Init関数は値やエラーを返すことができますか?
いいえ。initのシグネチャは変更されず、func init()で、パラメーターや戻り値はありません。
大規模なプロジェクトは、パッケージ間の依存関係を持つ複雑なinit関数に依存しており、浮動するランタイムエラーを引き起こしていました。
利点:
欠点:
Initは基本的またはテスト特化のタスクにのみ使用され、残りはmainから呼び出される明示的な関数に分離されます。起動順序は明らかで、テストが簡単です。
利点:
欠点: