mirror

Table of Contents

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

mirror は不要な []byte / string 変換を避けるために、より適切な代替関数の使用を提案するツールです。

解決する問題

strings パッケージと bytes パッケージには同等の機能を持つ関数が多数存在します。bytes.HasPrefix(b, []byte("prefix")) のように一度 []byte に変換してから処理するのは非効率です。strings パッケージの対応する関数を直接使うことで、不要な変換とメモリ割り当てを回避できます。

1
2
3
4
5
6
7
8
// Before: 不要な []byte 変換
func HasJSONPrefix(data []byte) bool {
return bytes.HasPrefix(data, []byte("{"))
}

func ContainsKeyword(s string) bool {
return bytes.Contains([]byte(s), []byte("keyword"))
}
1
2
3
4
5
6
7
8
// After: 適切な関数を使用
func HasJSONPrefix(data []byte) bool {
return bytes.HasPrefix(data, []byte("{")) // []byte 同士なので問題なし
}

func ContainsKeyword(s string) bool {
return strings.Contains(s, "keyword") // string のまま処理
}

設定

公式ドキュメント

設定オプションはありません。有効化するだけで動作します。

1
2
3
4
5
6
# .golangci.yml
version: "2"

linters:
enable:
- mirror

オプション

golangci-lint 経由では設定オプションはありません。

サンプル

検出例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// mirror が警告するパターン

import (
"bytes"
"regexp"
"strings"
"utf8"
)

// 1. strings → bytes の不要な変換
func example1(s string) bool {
return bytes.HasPrefix([]byte(s), []byte("test")) // use strings.HasPrefix instead
}

// 2. bytes → strings の不要な変換
func example2(b []byte) bool {
return strings.Contains(string(b), "test") // use bytes.Contains instead
}

// 3. regexp での不要な変換
func example3(re *regexp.Regexp, s string) []byte {
return re.ReplaceAll([]byte(s), []byte("new")) // use re.ReplaceAllString instead
}

// 4. utf8 での不要な変換
func example4(s string) int {
return utf8.RuneCount([]byte(s)) // use utf8.RuneCountInString instead
}

修正例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func example1(s string) bool {
return strings.HasPrefix(s, "test")
}

func example2(b []byte) bool {
return bytes.Contains(b, []byte("test"))
}

func example3(re *regexp.Regexp, s string) string {
return re.ReplaceAllString(s, "new")
}

func example4(s string) int {
return utf8.RuneCountInString(s)
}

注意点

  • stringsbytes パッケージはほぼ同じ API を持っているため、型に合ったパッケージを選択することで不要な変換を回避できる
  • regexp.Regexp にも Match / MatchStringReplaceAll / ReplaceAllString のようなペアがあり、mirror はこれらも検出する
  • utf8.RuneCountutf8.RuneCountInString も同様に検出対象
  • 自動修正(--fix)に対応しているため、大量の警告も一括で修正可能

参考リンク