mcpField
G
go-ops

go-ops

github.com/0xdarkmatter開発7851 回インストール2 週間前に更新
リポジトリ

go-ops について

Go 開発向けのリファレンススキルです。慣用的なコード、並行処理、テスト、プロジェクト構成、性能を扱い、概要とテーマ別資料を提供します。

主な機能

  1. 01慣用的な Go とエラー処理
  2. 02並行処理のパターンと指針
  3. 03インターフェースとジェネリクス
  4. 04テストとプロジェクト構成
  5. 05プロファイリングと性能改善

活用シーン

  1. 01エラー処理方法の選択
  2. 02Go の並行タスクの設計
  3. 03Go プロジェクトのパッケージ構成
  4. 04Go プロジェクトのテストや性能分析

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/0xdarkmatter/claude-mods --skill go-ops

インストール後、Claude Code で/go-opsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/
.gitkeep
references/
concurrency.md
error-handling.md
expert-insights.md
interfaces-generics.md
performance.md
project-structure.md
testing.md
scripts/
.gitkeep

詳細

Go の運用

慣用的なパターン、並行処理、本番環境での実践方法を網羅した Go スキルです。

モジュールのクイックスタート

# New module
go mod init github.com/user/project

# Add dependency
go get github.com/lib/pq@latest

# Tidy (remove unused, add missing)
go mod tidy

# Vendor dependencies
go mod vendor

# Workspace (multi-module)
go work init ./api ./shared
go work use ./cli

エラー処理の判断ツリー

What kind of error?
│
├─ Known, expected condition (e.g. "not found")
│  └─ Sentinel error: var ErrNotFound = errors.New("not found")
│     └─ Caller checks: errors.Is(err, ErrNotFound)
│
├─ Need to carry structured data (status code, field name)
│  └─ Custom error type: type ValidationError struct { Field, Message string }
│     └─ Implement Error() string
│     └─ Caller checks: errors.As(err, &validErr)
│
├─ Adding context to an existing error
│  └─ Wrap: fmt.Errorf("load config: %w", err)
│     └─ Preserves original for Is/As checks
│
├─ Truly unrecoverable (corrupted state, programmer bug)
│  └─ panic("invariant violated: ...")
│     └─ Almost never in library code
│
└─ Multiple errors from concurrent work
   └─ errors.Join(err1, err2) or multierr package
エラーのラップに関する規約
// Add context at each layer, don't repeat the function name
func LoadUser(id int) (*User, error) {
    row, err := db.Query("SELECT ...", id)
    if err != nil {
        return nil, fmt.Errorf("load user %d: %w", id, err)
    }
    // ...
}

並行処理の判断ツリー

What's the concurrency pattern?
│
├─ Run N independent tasks, collect results
│  └─ errgroup.Group (cancels on first error)
│
├─ Fire-and-forget background work
│  └─ go func() with context for cancellation
│     └─ ALWAYS handle the error or log it
│
├─ Producer/consumer pipeline
│  └─ Channels (buffered for throughput)
│     └─ Close channel when producer is done
│
├─ Rate-limited concurrent work
│  └─ Semaphore: make(chan struct{}, maxConcurrency)
│
├─ Shared mutable state
│  └─ sync.Mutex or sync.RWMutex
│     └─ Prefer channels if the state is simple
│
├─ One-time initialization
│  └─ sync.Once
│
└─ Wait for N goroutines to finish (no error collection)
   └─ sync.WaitGroup
errgroup のクイックスタート
import "golang.org/x/sync/errgroup"

g, ctx := errgroup.WithContext(ctx)
g.SetLimit(10) // max 10 concurrent goroutines

for _, url := range urls {
    g.Go(func() error {
        return fetch(ctx, url)
    })
}

if err := g.Wait(); err != nil {
    return fmt.Errorf("fetch urls: %w", err)
}

詳しく見る場合:ワーカープール、ファンアウト/ファンイン、パイプラインパターン、context のベストプラクティスについては、./references/concurrency.md を読み込んでください。

インターフェース設計

Accept interfaces, return structs.
// Good: function accepts interface
func Process(r io.Reader) error { ... }

// Good: return concrete type
func NewServer(cfg Config) *Server { ... }

// Bad: returning interface (hides implementation, prevents extension)
func NewServer(cfg Config) ServerInterface { ... }
標準ライブラリでよく使われるインターフェース
インターフェースメソッド用途
io.ReaderRead([]byte) (int, error)あらゆるバイトソース
io.WriterWrite([]byte) (int, error)あらゆるバイト出力先
io.CloserClose() errorリソースのクリーンアップ
fmt.StringerString() string文字列表現
errorError() stringエラー値
sort.InterfaceLen, Less, Swapカスタムソート
http.HandlerServeHTTP(w, r)HTTP ハンドラー
encoding.BinaryMarshalerMarshalBinary() ([]byte, error)バイナリーエンコーディング
関数オプションパターン
type Option func(*Server)

func WithPort(port int) Option {
    return func(s *Server) { s.port = port }
}

func WithTimeout(d time.Duration) Option {
    return func(s *Server) { s.timeout = d }
}

func NewServer(opts ...Option) *Server {
    s := &Server{port: 8080, timeout: 30 * time.Second} // defaults
    for _, opt := range opts {
        opt(s)
    }
    return s
}

// Usage
srv := NewServer(WithPort(9090), WithTimeout(5*time.Second))

詳しく見る場合:ジェネリクス、型制約、埋め込み、型アサーションについては、./references/interfaces-generics.md を読み込んでください。

テストのクイックリファレンス

// Table-driven test
func TestAdd(t *testing.T) {
    tests := []struct {
        name     string
        a, b     int
        expected int
    }{
        {"positive", 1, 2, 3},
        {"zero", 0, 0, 0},
        {"negative", -1, -2, -3},
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got := Add(tt.a, tt.b)
            if got != tt.expected {
                t.Errorf("Add(%d, %d) = %d, want %d", tt.a, tt.b, got, tt.expected)
            }
        })
    }
}
# Run tests
go test ./...

# With coverage
go test -cover -coverprofile=coverage.out ./...
go tool cover -html=coverage.out

# Run specific test
go test -run TestAdd ./pkg/math/

# Benchmarks
go test -bench=. -benchmem ./...

# Race detector
go test -race ./...

# Fuzz testing
go test -fuzz=FuzzParse ./...

詳しく見る場合:インターフェースを使ったモック、httptest、testcontainers、ゴールデンファイルについては、./references/testing.md を読み込んでください。

よくある落とし穴

落とし穴理由対処法
nil スライスと空スライスvar s []int は nil、s := []int{} は空です。json.Marshal の結果はそれぞれ null と [] になりますJSON が重要な場合は make([]int, 0) または []int{} を使います
ゴルーチンリーク読み手/書き手がいないチャネルでゴルーチンがブロックされますcontext.WithCancel を使い、必ず終了経路を用意します
ループ内の defer遅延呼び出しは関数が戻るまで実行されませんループ本体をクロージャーで囲むか、明示的にクリーンアップします
インターフェースの nil に関する落とし穴(*MyType)(nil) を error インターフェースに代入すると、== nil になりませんnil の型付きポインターではなく、明示的に nil を返します
range 変数のキャプチャループ変数は再利用されます(Go 1.22 より前)go func(v T) { ... }(v) を使うか、Go 1.22 以降にアップグレードします
ループ内での文字列連結O(n^2) のメモリー割り当てが発生しますstrings.Builder を使います
sync.WaitGroup での Go 実行後の Add競合状態が発生しますgo func() の前に wg.Add(1) を呼び出します
バッファーなしチャネルのデッドロック送信と受信を同時に行う必要がありますバッファー付きチャネルまたは別々のゴルーチンを使います
map は並行利用に安全ではありません競合状態が発生し、クラッシュする可能性がありますsync.Mutex または sync.Map を使います

プロジェクト構成

project/
├── cmd/
│   ├── api/main.go           # Entry points
│   └── worker/main.go
├── internal/                  # Private packages
│   ├── handler/
│   ├── service/
│   └── repository/
├── pkg/                       # Public packages (optional)
├── go.mod
├── go.sum
├── Makefile                   # or justfile
└── .golangci.yml

詳しく見る場合:ワークスペースモード、ビルドタグ、ldflags、リンター設定については、./references/project-structure.md を読み込んでください。

パフォーマンスのクイックリファレンス

# CPU profile
go test -cpuprofile=cpu.prof -bench=. ./...
go tool pprof cpu.prof

# Memory profile
go test -memprofile=mem.prof -bench=. ./...
go tool pprof -alloc_space mem.prof

# Trace
go test -trace=trace.out ./...
go tool trace trace.out

# Escape analysis
go build -gcflags='-m' ./...
最適化適用場面パターン
スライスの事前割り当てサイズが既知の場合make([]T, 0, n)
strings.Builder文字列連結var b strings.Builder
sync.Pool同じ型の頻繁な割り当て/解放pool.Get() / pool.Put()
構造体フィールドのアラインメントメモリーが重要な場合サイズの大きい順にフィールドをまとめます
バッファーの再利用I/O が多い場合bufio.NewReaderSize(r, 64*1024)

詳しく見る場合:pprof の手順、ベンチマークパターン、エスケープ解析については、./references/performance.md を読み込んでください。

リファレンスファイル

詳しく知りたいトピックについては、以下を読み込んでください。各ファイルは単独で参照できます。

リファレンス読み込むタイミング
./references/concurrency.mdGoroutine、チャネル、コンテキスト、同期プリミティブ、ワーカープール、パイプライン
./references/error-handling.mdエラーのラップ、センチネルエラー、カスタム型、複数のエラー、panic/recover
./references/testing.mdテーブル駆動テスト、モック、httptest、ベンチマーク、ファジング、testcontainers、ゴールデンファイル
./references/interfaces-generics.mdインターフェース設計、埋め込み、型アサーション、ジェネリクス、型制約
./references/project-structure.md標準レイアウト、go.mod、ワークスペース、ビルドタグ、ldflags、golangci-lint
./references/performance.mdpprof、trace、ベンチマーク、エスケープ解析、sync.Pool、構造体のアラインメント
./references/expert-insights.mdHTTP サーバー(Go 1.22 のルーティング)、グレースフルシャットダウン、http.Client のチューニング、JSON ヘルパー

関連項目

  • docker-ops - Go バイナリのマルチステージビルド(scratch/distroless)
  • ci-cd-ops - Go の CI パイプライン、Go モジュールのキャッシュ、goreleaser
  • testing-ops - 言語をまたいだテスト戦略

コメント