---
title: "eg（Goのexample-based refactoringツール）とは｜テンプレートで一括リファクタリングする使い方"
url: "https://www.issoh.co.jp/tech/details/3400/"
published: 2024-08-27
updated: 2026-07-21
categories: ["Go"]
publisher: "株式会社一創"
---

# eg（Goのexample-based refactoringツール）とは｜テンプレートで一括リファクタリングする使い方

「eg tool」で検索してたどり着くのは、多くの場合Go公式ツール群 `golang.org/x/tools` に含まれる `eg` コマンドです。GUIアプリでも独立した製品でもなく、**コード例（example）でリファクタリングを指定するコマンドラインツール**で、名前は「e.g.（例えば）」に由来します。この記事では、その導入方法・テンプレート（before/after関数）の書き方・実行手順・使えない場面までを一次情報にもとづいて整理します。

## まとめ：egは「変換前後のコード例」で一括置換するGoのリファクタリングツール

- **正体**：`golang.org/x/tools/cmd/eg`。Goのソースを型情報つきで解析し、パターンに一致する式をまとめて置換する。
- **導入**：`go install golang.org/x/tools/cmd/eg@latest` の1行。
- **指定方法**：`before`／`after` という同じ型の関数2つを書いたテンプレートファイルを渡す。beforeが検索パターン、afterが置換後。
- **実行**：`eg -t template.go <パッケージ>` で結果を標準出力に確認し、問題なければ `-w` で上書き。
- **限界**：置換できるのは「式→式」だけ。文の書き換え・型をまたぐ一般化はできず、追加されたimportは自動削除されない（`goimports`で後処理）。

## egとは：型を理解して式を置換するexample-based refactoring

egは、正規表現ではなく**実際のGoコードの例**で「この式をこの式に置き換えたい」と宣言する方式のリファクタリングツールです。指定したパッケージ内のすべてのGoコードを解析し、パターンに一致する箇所を置換後の式に書き換えます。

特徴は、単なる文字列置換ではなく**型情報を使って一致を判定する**点です。同名のメソッドでもレシーバの型が違えば誤爆せず、意味的に同じ式だけを対象にできます。ソースコードを実行せずに構造と型を読む点は[静的解析とは何か？ソースコードを実行せずに品質を確保する手法](https://www.issoh.co.jp/tech/details/7475/)で扱う静的解析の一種で、egはその仕組みを「一括書き換え」に応用したものと捉えると理解しやすい。

## インストールと基本コマンド

Goがインストール済みなら、次の1行で `$GOPATH/bin`（通常 `$HOME/go/bin`）に `eg` が入ります。

```
go install golang.org/x/tools/cmd/eg@latest
```

基本の呼び出し形は次のとおりです。`<パッケージ>` にはインポートパスや `./...`（カレント配下すべて）を指定します。

```
eg -t template.go [-w] [-transitive] <パッケージ>
```

主なフラグは以下です。

| フラグ               | 意味                                                      |
| ----------------- | ------------------------------------------------------- |
| `-t template.go`  | リファクタリングを定義するテンプレートファイル（必須）                             |
| `-w`              | 結果を標準出力ではなく元ファイルへ直接書き戻す                                 |
| `-transitive`     | 指定パッケージだけでなく依存先パッケージも対象にする                              |
| `-tags tag,...`   | 適用するビルドタグ（カンマ区切り）                                       |
| `-beforeedit cmd` | 各ファイルを編集する前に実行するコマンド。`{}` がファイル名に置換される（例：チェックアウトやchmod） |
| `-v`              | マッチングの詳細診断を表示する                                         |
| `-help`           | テンプレートの説明を含む詳細ヘルプを表示する                                  |

## テンプレート（before／after関数）の書き方

変換内容は、**同じ型シグネチャを持つ `before` と `after` の2関数**を書いたGoファイルで指定します。各関数の本体は「1つの式（return文または式文）」だけにします。beforeの式がパターン、afterの式が置換後です。

```
package P

import (
	"errors"
	"fmt"
)

func before(s string) error { return fmt.Errorf("%s", s) }
func after(s string) error  { return errors.New(s) }
```

関数の**引数はワイルドカード**として働き、その型に代入可能な任意の式に一致します。同じ引数がパターン内に複数回現れる場合は、入力側でも同一の式でなければ一致しません。上のテンプレートを次のように適用すると、

```
eg -t template.go -w ./...
```

コード中の `fmt.Errorf("%s", "error: "+msg)` が `errors.New("error: "+msg)` に置き換わります。`"error: "+msg` という具体的な式がワイルドカード `s` に収まっている点が、型を見たうえでの一致です。

## 実行手順：まず標準出力で確認し、-wで確定する

egは破壊的な一括置換なので、いきなり `-w` を付けないのが安全です。手順は次のようにします。

- **差分を確認**：`-w` なしで `eg -t template.go ./...` を実行すると、書き換え後のコードが標準出力に出る。意図しない箇所が変わっていないか目視する。
- **書き戻し**：問題なければ `-w` を付けて再実行し、ファイルへ反映する。
- **依存先も直す**：ライブラリ側のAPI変更に追随するなど、依存パッケージまで一括で直したいときだけ `-transitive` を足す。
- **編集前フック**：バージョン管理で読み取り専用のファイルを扱う場合などは、`-beforeedit` にチェックアウトコマンドを渡す。

非推奨になったAPIの呼び出しを新APIへ機械的に寄せる、社内共通ライブラリの関数名変更に全リポジトリで追随する、といった「同じ形の式を何百箇所も直す」場面で威力を発揮します。手作業の置換と違い型で判定するため、たまたま文字列が一致しただけの別物を巻き込みません。リファクタリングをどの時点で入れるべきかの判断は[リファクタリングを行うべきタイミングとその判断基準](https://www.issoh.co.jp/column/details/2836/)を参照してください。

## egが苦手な場面：式単位という制約を先に知る

egは万能ではありません。設計上できないことを先に把握しておくと、無理な使い方で時間を溶かさずに済みます。公式ヘルプが挙げる主な制約は次のとおりです。

- **置換できるのは「式」だけ**：文（if文・代入文・複数ステートメント）の書き換えには使えない。
- **型をまたぐ一般化ができない**：intやint64など「すべての整数型」といったまとめ方や、置換前後で型が変わる変換は表現できない。
- **関数リテラルはパターンに書いても一致しない**。
- **構造体リテラルの表記ゆれ**：`T{x}` と `T{K: x}` を1つのテンプレートで両方一致させることはできない。
- **ドットインポート禁止**：テンプレート内でドットインポートは使えない。ドットインポートや別名インポートを含むコードでは、置換結果の識別子が正しくならないことがある。
- **importは足すが消さない**：置換で新たに必要になったimportは自動追加されるが、不要になったimportは残る。仕上げに `goimports` を通す。

また公式ドキュメント自身が「変換が型エラーを生まないと保証するのは一般には非常に複雑」と明記しています。**置換後は必ずコンパイルとテストで検証する前提のツール**だと考え、無検証で `-w` を回さないことが実務上の鉄則です。

## 他のリファクタリング手段との使い分け

Goには目的別に別の手段があり、egが向くのは「同じ形の式を型安全に一括置換する」ケースに絞られます。

| やりたいこと             | 向くツール                      |
| ------------------ | -------------------------- |
| 同じ形の式を型を見て一括置換     | `eg`                       |
| 構文ベースの単純な書き換え      | `gofmt -r`                 |
| 識別子（変数・関数・型名）の改名   | `gopls` のrename／`gorename` |
| 抽出・移動などIDE上の対話的な操作 | IDEのリファクタリング機能             |

`gofmt -r` は構文パターンで置換するため手軽ですが型を見ません。egは型情報を使う分、意味的に同じ式だけを狙えます。一方、変数名や関数名そのものを変えたいなら改名専用の `gopls`／`gorename` が適切で、egの守備範囲ではありません。IDEでの抽出・移動を含む対話的な操作については[IntelliJ IDEAとEclipseの違いを徹底比較｜補完・Spring・料金と選び方【2026】](https://www.issoh.co.jp/tech/details/3698/)も参考になります。コード品質改善を自動化ツール全体でどう組むかは[コード品質管理における自動化ツールの活用方法](https://www.issoh.co.jp/tech/details/5209/)で整理しています。

## よくある質問

### egの読み方と名前の由来は？

「e.g.（exempli gratia＝例えば）」に由来する名前で、コード例でリファクタリングを指定する方式を表しています。コマンド名としては `eg` の2文字です。

### 「eg.go」とは何ですか？

`eg.go` はegコマンド本体のソースファイル名です（`cmd/eg/eg.go`、および実装本体の `refactor/eg/eg.go`）。ツールの中身を確認したいときに読むファイルで、別製品ではありません。

### 「eg software」「eg tools」という別のソフトですか？

検索では紛れますが、「eg software」「eg tools」（複数形）と表記されるものも、指しているのはこのGoのコマンドラインツール `eg` です。独立したパッケージソフトやGUIアプリケーションではありません。

### gofmt -rとの違いは？

`gofmt -r` は構文パターンによる置換で型を考慮しません。egは型情報を使って一致を判定するため、名前が同じでも型の異なる式を巻き込まずに置換できます。

### 置換後にimportが壊れたように見えるのはなぜ？

egは必要なimportを追加しますが、不要になったimportの削除は行いません。実行後に `goimports` を通してimportを整理してください。

## 関連記事

- [リファクタリングを行うべきタイミングとその判断基準](https://www.issoh.co.jp/column/details/2836/)
- [静的解析とは何か？ソースコードを実行せずに品質を確保する手法](https://www.issoh.co.jp/tech/details/7475/)
- [コード品質管理における自動化ツールの活用方法](https://www.issoh.co.jp/tech/details/5209/)
- [IntelliJ IDEAとEclipseの違いを徹底比較｜補完・Spring・料金と選び方【2026】](https://www.issoh.co.jp/tech/details/3698/)

---

出典: [eg（Goのexample-based refactoringツール）とは｜テンプレートで一括リファクタリングする使い方](<https://www.issoh.co.jp/tech/details/3400/>)（株式会社一創）
