nestif

Table of Contents

  1. 解決する問題
  2. 設定
  3. オプション
  4. 複雑度の計算ルール
  5. サンプル
    1. 検出例
    2. 修正例
  6. 注意点
  7. 参考リンク

nestif は深くネストされた if 文を検出するツールです。

解決する問題

if 文のネストが深くなると、コードの理解に必要な認知的コストが急激に増加します。ネストが 3〜4 段以上になると条件の組み合わせを頭の中で追跡するのが困難になり、バグの温床になります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Before: ネストが深い(複雑度: 9)
func ProcessOrder(ctx context.Context, order Order) error {
if order.ID != "" { // +1
if order.Status == StatusPending { // +2 (ネスト1)
if order.Total > 0 { // +3 (ネスト2)
if order.CustomerID != "" { // +4 (ネスト3)
return save(ctx, order)
} else { // +1
return errors.New("customer required")
}
}
}
}
return errors.New("invalid order")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// After: 早期リターンでフラット化
func ProcessOrder(ctx context.Context, order Order) error {
if order.ID == "" {
return errors.New("order ID required")
}
if order.Status != StatusPending {
return errors.New("order not pending")
}
if order.Total <= 0 {
return errors.New("order total must be positive")
}
if order.CustomerID == "" {
return errors.New("customer required")
}
return save(ctx, order)
}

設定

公式ドキュメント

1
2
3
4
5
6
7
8
9
# .golangci.yml 設定例
version: "2"

linters:
enable:
- nestif
settings:
nestif:
min-complexity: 5

オプション

オプション デフォルト 説明
min-complexity int 5 この値以上の複雑度を持つ if 文を報告する

複雑度の計算ルール

構造 加算
if +1
else if +1
else +1
ネストされた if +ネスト深さ(深いほど加算が大きい)

サンプル

検出例

1
2
3
4
5
6
7
8
9
10
11
12
13
// nestif が警告: `if user.IsActive()` is nested (complexity: 6)
func CanAccess(user User, resource Resource) bool {
if user.IsActive() { // +1
if user.HasRole("admin") { // +2 (ネスト1)
return true
} else if user.HasRole("editor") { // +1
if resource.IsPublished() { // +3 (ネスト2)
return true
}
}
}
return false
}

修正例

1
2
3
4
5
6
7
8
9
10
11
12
func CanAccess(user User, resource Resource) bool {
if !user.IsActive() {
return false
}
if user.HasRole("admin") {
return true
}
if user.HasRole("editor") && resource.IsPublished() {
return true
}
return false
}

注意点

  • min-complexity のデフォルトは 5。厳しくするなら 3〜4、緩めるなら 7〜8 が目安
  • 早期リターン(guard clause)が最も効果的なリファクタリング手法。条件を反転して異常系を先に返す
  • else if チェーンは switch に置き換えるとネストが浅くなる
  • gocognit は関数全体の複雑度を測るのに対し、nestif は個々の if 文のネスト深さに特化している

参考リンク