exhaustruct は構造体のすべてのフィールドが初期化されているかをチェックするツールです。
解決する問題
構造体の初期化時にフィールドを省略すると、ゼロ値が暗黙的に設定されます。新しいフィールドが追加された際に初期化漏れが発生しやすく、意図しないデフォルト値によるバグの原因になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| type DBConfig struct { Host string Port int User string Password string SSLMode string }
func NewDBConfig() DBConfig { return DBConfig{ Host: "localhost", Port: 5432, } }
|
1 2 3 4 5 6 7 8 9 10
| func NewDBConfig() DBConfig { return DBConfig{ Host: "localhost", Port: 5432, User: "app", Password: "", SSLMode: "disable", } }
|
設定
公式ドキュメント
1 2 3 4 5 6 7 8 9 10 11 12 13
| version: "2"
linters: enable: - exhaustruct settings: exhaustruct: include: - '.*Config$' - '.*Options$' exclude: - 'net/http\.Client'
|
オプション
| オプション |
型 |
デフォルト |
説明 |
include |
[]string |
[] |
チェック対象の型名の正規表現リスト(パッケージパスを含むフルネームでマッチ) |
exclude |
[]string |
[] |
チェック除外の型名の正規表現リスト(include より優先) |
allow-empty |
bool |
false |
空の構造体リテラル(T{})をグローバルに許可する |
allow-empty-returns |
bool |
false |
return 文での空の構造体リテラルを許可する |
allow-empty-declarations |
bool |
false |
変数宣言での空の構造体リテラルを許可する |
allow-empty-rx |
[]string |
[] |
空の構造体リテラルを許可する型名の正規表現リスト |
include / exclude の使い分け
1 2 3 4 5 6 7 8 9 10 11
| linters: settings: exhaustruct: include: - '.*Config$' - '.*Options$' exclude: - 'net/http\..*' - 'google\.golang\.org/.*'
|
サンプル
検出例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
type ServerConfig struct { Host string Port int ReadTimeout time.Duration WriteTimeout time.Duration MaxBodySize int64 }
func NewServer() ServerConfig { return ServerConfig{ Host: "0.0.0.0", Port: 8080, } }
func DefaultConfig() ServerConfig { return ServerConfig{} }
|
修正例
1 2 3 4 5 6 7 8 9
| func NewServer() ServerConfig { return ServerConfig{ Host: "0.0.0.0", Port: 8080, ReadTimeout: 30 * time.Second, WriteTimeout: 30 * time.Second, MaxBodySize: 1 << 20, } }
|
注意点
include を指定しない場合、すべての構造体がチェック対象になる。プロジェクト全体に適用すると外部ライブラリの型でも警告が出るため、include で対象を絞るのが推奨
exclude は include より優先される。外部パッケージの型を除外したい場合に使用する
//exhaustruct:enforce ディレクティブをコードに付与すると、グローバル設定で除外されていてもその構造体を強制チェックできる
allow-empty-returns: true にすると、エラー時の return Config{}, err パターンを許容できる
- テストコードでは
allow-empty-declarations: true にすると、テスト用の空構造体宣言を許容できる
参考リンク