predeclared

Table of Contents

  1. 解決する問題
  2. 設定
  3. オプション
  4. 事前宣言済み識別子の一覧
    1. 型
    2. 関数
    3. 定数
    4. ゼロ値
  5. サンプル
    1. 検出例
    2. 修正例
  6. 注意点
  7. 参考リンク

predeclared は Go の事前宣言済み識別子(new、make、len、int など)をシャドーイングしている宣言を検出するツールです。

解決する問題

Go ではビルトイン関数や型の名前を変数名や関数名として再宣言できてしまいます。シャドーイングすると本来のビルトイン機能が使えなくなり、予期しないバグや混乱を引き起こします。

1
2
3
4
5
6
7
8
9
10
11
12
// Before: ビルトインをシャドーイング
func process(data []byte) {
len := len(data) // len をシャドーイング → 以降 len() が使えない
copy := make([]byte, len) // copy をシャドーイング → 以降 copy() が使えない
_ = copy
}

// 型名のシャドーイング
func parse(s string) {
string := s // string 型をシャドーイング
_ = string
}
1
2
3
4
5
6
7
8
9
10
11
// After: 適切な変数名を使用
func process(data []byte) {
dataLen := len(data)
buf := make([]byte, dataLen)
_ = buf
}

func parse(s string) {
str := s
_ = str
}

設定

公式ドキュメント

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

linters:
enable:
- predeclared
settings:
predeclared:
ignore:
- new
qualified-name: false

オプション

オプション 型 デフォルト 説明
ignore []string [] チェック対象外にする事前宣言済み識別子のリスト
qualified-name bool false メソッド名やフィールド名もチェック対象に含める

事前宣言済み識別子の一覧

型

bool, byte, comparable, complex64, complex128, error, float32, float64, int, int8, int16, int32, int64, rune, string, uint, uint8, uint16, uint32, uint64, uintptr, any

関数

append, cap, clear, close, complex, copy, delete, imag, len, make, max, min, new, panic, print, println, real, recover

定数

true, false, iota

ゼロ値

nil

サンプル

検出例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// predeclared が警告するパターン

// 変数名がビルトイン関数と衝突
func example1() {
len := 10 // variable "len" has same name as predeclared identifier
cap := 20 // variable "cap" has same name as predeclared identifier
_ = len
_ = cap
}

// 関数名がビルトイン型と衝突
func error() string { // function "error" has same name as predeclared identifier
return "something went wrong"
}

// 型名がビルトインと衝突
type int struct { // type "int" has same name as predeclared identifier
value int64
}

修正例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func example1() {
length := 10
capacity := 20
_ = length
_ = capacity
}

func newError() string {
return "something went wrong"
}

type Integer struct {
value int64
}

注意点

  • qualified-name: true にするとメソッド名やフィールド名もチェック対象になる(例: type Foo struct { len int } が検出される)。厳しすぎる場合は false のままにする
  • new は Go のビルトインだが変数名として使われることが比較的多い。許容する場合は ignore に追加する
  • シャドーイングはコンパイルエラーにならないため、静的解析での検出が重要

参考リンク