[Go 再学習] Go の interface を理解する

Go の再学習をしている最中なのですが、学習当初 Go Interface は「なんとなく分かるが使いこなせない」という感覚を持っていました。自分のコードでも使っているのですが、どのようなパターンで使えるのかを網羅的には知っていない状態だったのでこれを機に調べてみました。この記事では基本的な定義から実務でよく登場するパターンまでをサンプルコードと共に整理しました。 コードは以下のレポジトリにあります。 https://github.com/jedipunkz/go-tips interface とは interface はメソッドのシグネチャの集合を定義する型です。ある型が interface に定義されたメソッドをすべて持っていれば、自動的にその interface を満たします。 この設計により、既存のコードを変更せずに後から interface に適合させることができます。 パターン1: 基本的な interface 最もシンプルな interface の定義と利用です。Shape interface を定義し、Circle と Rectangle がそれを実装します。 使い所 図形の面積や周長を計算する処理を書く場合、Circle や Rectangle ごとに別々の関数を用意すると、新しい図形が増えるたびに呼び出し側の修正が必要になります。Shape interface を定義して関数が Shape を受け取るようにすると、新しい図形を追加しても既存の関数はそのまま使え、拡張が容易になります。 package main import ( "fmt" "math" ) // Shape インターフェースを定義する // メソッドセットを持つ型はこのインターフェースを満たす type Shape interface { Area() float64 Perimeter() float64 } type Circle struct { Radius float64 } func (c Circle) Area() float64 { return math.Pi * c.Radius * c.Radius } func (c Circle) Perimeter() float64 { return 2 * math.Pi * c.Radius } type Rectangle struct { Width, Height float64 } func (r Rectangle) Area() float64 { return r.Width * r.Height } func (r Rectangle) Perimeter() float64 { return 2 * (r.Width + r.Height) } // インターフェース型を引数に取ることで、どの Shape 実装でも受け付ける func printShapeInfo(s Shape) { fmt.Printf("面積: %.2f, 周長: %.2f\n", s.Area(), s.Perimeter()) } func main() { c := Circle{Radius: 5} r := Rectangle{Width: 4, Height: 6} fmt.Print("Circle: ") printShapeInfo(c) fmt.Print("Rectangle: ") printShapeInfo(r) } printShapeInfo は Shape を受け取るだけで、Circle か Rectangle かを意識しません。新たに Triangle を追加したとしても、Area() と Perimeter() を実装するだけで既存コードの変更なく動きます。 ...

2026-04-13 · 5 分 · jedipunkz

[Go 再学習] Go の goroutine と channel を理解する

再び Go の学習を再開していて、以前理解が曖昧だった点を重点的に学び直しています。そのうちの1つ goroutine, channel について記事にしょうと思います。 Go の並行処理は goroutine と channel という2つの仕組みを中心に設計されています。channel を通じてデータをやり取りすることで安全な並行処理を実現できます。この記事ではサンプルコードを交えて解説します。 コードは以下のレポジトリにあります。 https://github.com/jedipunkz/go-tips goroutine とは goroutine は Go のランタイムが管理する軽量なスレッドです。go キーワードをつけて関数を呼び出すだけで並行実行できます。 通常の関数呼び出しは呼び出し元が処理完了を待ちますが、go をつけると呼び出し元はすぐに次の処理へ進み、関数は別の goroutine で並行して動きます。 channel とは channel は goroutine 間でデータを安全にやり取りするためのパイプです。make(chan T) で作成し、<- 演算子で送受信します。 送信: ch <- value 受信: value := <-ch channel を使うと goroutine 間で双方向にデータをやり取りできます。 channel にはバッファなしとバッファありの2種類があります。バッファなし channel は送受信が揃うまでブロックするため、goroutine 間の同期点として機能します。バッファあり channel はバッファに空きがある限り送信側はブロックせず先へ進めます。 パターン1: 基本的な channel の使い方 まずは最もシンプルなパターンです。producer goroutine が値を送信し、main goroutine が受信します。 使い所 Web から複数のファイルをダウンロードして DB に保存するような処理を考えると、ネットワーク待ちや DB への書き込み待ちがほとんどで CPU はほぼ遊んでいます。こういった I/O バウンドな処理では、1件ずつ順番に処理するより goroutine と channel でパイプライン化するほうが効率的です。たとえば「URL リストを読み込む goroutine」と「その URL から HTTP GET する goroutine」を分離し、channel でつなぐことで取得と後続処理を並行して進められます。 ...

2026-04-04 · 5 分 · jedipunkz

複数の Claude Code エージェントを1つのターミナルから起動・監視するツールを作った

jedipunkz です。 背景 Claude Code を日常的に使う中で、複数のエージェントを同時に動かしたいというシーンが増えてきました。例えば複数の独立したタスクを並列で走らせたいとき、それぞれのエージェントが今どんな状態にあるかをターミナル1つで把握したいと思っていました。 幾つかのアプローチについて 以前Zellij を使って Claude Code のマルチエージェント並列・直列実行環境を作った という記事を書いたのですが、これは1つのレポジトリに対して複数の機能開発・リファクタ・その他修正を並列でそれぞれ別の Claude Code で行い最終的にそれぞれの git worktree 上の差分をマージする統合管理 Claude Code を実現するものでした。これは Claude Code 純正の機能 Sub Agents とは異なり複数の Claude Code をオーケストレーションするモノとして利用していたのですが、対象が1つのレポジトリに限定されること、また最終的にそれぞれの差分をマージするのであれば Sub Agents で事足りる事も多くなってきていました。 それに対して最近の要件としては下記のように変化してきました。 複数のレポジトリの修正を行いたい それぞれのエージェントのオーケストレーションよりも、それぞれの可視化と管理をしたい そこで Go で ax というツールを作りました。 リポジトリはこちらです: https://github.com/jedipunkz/ax ax とは ax は「1つのターミナルから複数の Claude Code エージェントを起動・監視する」ためのCLI ツールです。 主な機能は以下の通りです。 ax agent でエージェントを起動(git リポジトリ内では自動で git worktree を作成) ax dash で TUI ダッシュボードを開き、全エージェントの状態をリアルタイムで確認 バックグラウンドのデーモンプロセスが Unix ドメインソケット経由でエージェントと TUI 間の状態を管理 スクリーンショット 表示は下記のようになります。vim キーバインドで移動出来ます。 ...

2026-03-14 · 2 分 · jedipunkz

Zellij を使って Claude Code のマルチエージェント並列・直列実行環境を作った

jedipunkz🚀 です。 Claude Code を日常的に使う中で、大きなタスクを複数の独立したサブタスクに分けて並列処理させたいというニーズが出てきました。例えばコードのリファクタリングとテスト追加を同時に進めたり、複数ファイルへの独立した修正を並行して行ったりといったケースです。 2026年2月に Claude Code Agent Teams という機能が出てきたのですが、あくまでも1つのタスクの中で複数のサブエージェントを稼働させるものだったので自分としては期待していたものと若干異なりました。やりたいのは親 Claude Code のプロンプトから指示を出して複数のタスクを行ってくれる子 Claude Code のオーケストレーションでした。 そこで、Zellij の Pane 管理と git worktree を組み合わせて、親 Claude Code が複数の子エージェントを Zellij Pane として起動しタスクを並列・直列実行させる SKILL「zellij-swarm」を作りました。この記事ではその仕組みと使い方を紹介します。 SKILL は以下に置いています: https://github.com/jedipunkz/dotfiles/tree/main/.claude/skills/zellij-swarm 概要 親 Claude Code に対して「swarm で〜して」と自然言語で指示を出すと、タスクを複数のサブタスクに分解し、それぞれを別々の Zellij Pane で動く子 Claude Code エージェントとして起動するオーケストレーションの仕組みです。 各エージェントは独立した git worktree 上で作業し、完了後に親エージェントが各ブランチをマージして Git worktree の後片付けまで行います。 タスク間に依存関係がある場合は フェーズ に分割して対応します。同一フェーズ内のエージェントは並列実行、フェーズ間は直列実行です。 実行フローの構造 パターン 1: 並列のみ (依存関係なし) タスク A と B が互いに独立している場合、1 フェーズで並列実行して終了します。 [agent-a] ─┐ ├─ run-phase.sh ── merge [agent-b] ─┘ |-------| phase 1 パターン 2: 並列 → 直列 (フェーズ制御) タスク C がタスク A・B の結果に依存する場合、2 フェーズに分けます。Phase 1 完了・マージ後に Phase 2 が起動するため、C は A・B の成果を引き継いだ状態で作業できます。 ...

2026-02-21 · 3 分 · jedipunkz

コマンド・ブランチ検索を行う Fish Plugin を Go で作った話

jedipunkz です。 今回は自作した Fish シェルの Plugin である fuzz.fish を紹介します。 fuzz.fish は Fish Shell のコマンド履歴と Git ブランチをインクリメンタルサーチできる Fish Plugin [です。Go と charmbracelet/bubbletea を使って TUI を実装しており、Fisher でインストールすると自動的にバイナリがビルドされます。 ソースコード https://github.com/jedipunkz/fuzz.fish スクリーンショット ちょっと見た感じわかりにくいですがコマンド検索とブランチ検索に対応しています。 開発動機 幾つか小さなツールはこれまでも作ってきましたが利用する機会が減るとメンテナンスも怠りがちなことに気が付き、自分自身がよく使うツールを作ろうと思ったのがきっかけです。 そして普段から Fish をシェルとして使っていますがコマンド履歴検索や Git ブランチの切り替えをより効率的に出来れば何より自分にとって便利なツールになる予感がありました。。既存のツールもありますが、以下の点を満たすものを作りたいと考えました。 主な機能 fuzz.fish は以下の機能を持っています。今後も追加していく予定です。 コマンド履歴と Git ブランチ検索を1つのツールで切り替えられる コマンド履歴検索時にそのコマンドを実行した前後のコマンドの表示・時間情報も付け加えて表示 Fisher でシンプルにインストールできる Go で実装して高速に動作且つ Fish スクリプト単体では実現出来ない機能追加に備える インストール方法 ※ 事前に Go がローカルにインストールされている必要があります。 ※ インストール時に自動的に GitHub からソースをクローンし、Go でバイナリをビルドします。 Fisher を使ってインストールします。 fisher install jedipunkz/fuzz.fish 使い方 コマンド履歴検索 (Ctrl+R) 基本的な使い方です。Fish プロンプトで Ctrl+R を押すとコマンド履歴のファジー検索が起動します。 ...

2026-01-17 · 1 分 · jedipunkz

Discord サーバ運営を補助する Go 実装のボット開発

自分は Discord サーバの運営を行っているのですがその運営の補助をしてもらうためにボット開発を行っています。Go で Discord ボットを開発しメンバー数の推移やログ分析を行うシステムを構築している話とまたその他幾つか機能をもっていて日々の作業の効率化を図っています。この記事ではそのボットの紹介をさせて頂きます。 ※ 以前の記事 https://jedipunkz.github.io/post/discord-exporter/ の内容を含んでいます システム構成 このシステムは以下の3つの主要コンポーネントで構成されています。 Discord ボット(padawan) - Go 製の Discord ボット discord-exporter - Go 実装の Discord サーバメトリクス収集用 Prometheus Exporter 分析基盤 - DuckDB を用いた構造化ログの分析コンテナ 構成図は下記になります。Prometheus Exporter は Discord API から情報を取得し Prometheus Server にメトリクスを提供。Prometheus Server はそのメトリクスをポーリングしストレージにデータを蓄積。Grafana はそれをデータソースとして参照。padawan は Go 実装のボットで Discord API やその他ゲーム用 API 等を参照し機能提供。ボットと隣接してある DuckDB コンテナはボットのログを分析するための Go 実装の CLI を備える。 構成の詳細 ボットの構成 padawan と名前のボットとそのボットのログを分析する DuckDB コンテナで構成されています。 # padawan/docker-compose.yaml services: padawan: build: context: . dockerfile: Dockerfile volumes: - ./data:/root/data - ./logs:/logs restart: always duckdb: build: context: . dockerfile: Dockerfile.duckdb volumes: - ./logs:/logs:ro restart: "no" profiles: - tools discord-exporter の構成 Go 実装の Discord API から情報を収集する Exporter を中心とし Grafana, Prometheus Server を構成としても持っています。 ...

2025-12-30 · 5 分 · jedipunkz

Claude Code から OpenCode へ移行した話

jedipunkz🚀 です。 最近、AI コーディングアシスタントとして使っていた Claude Code から OpenCode に移行しました。この記事では OpenCode の優れた機能と、なぜ移行を決めたのかの決めてを紹介します。 注記 (2025-12-28) OpenCode プロジェクトは、2024年7月に開発元の Charm 社による買収と運営方針を巡って、コントリビューター間で論争が発生しました。その後、Charm 版は Crush としてリブランドされ、現在の OpenCode は SST 組織によって https://github.com/sst/opencode で開発が継続されています。両プロジェクトは現在も別々のツールとして存在しており、この記事では SST 版の OpenCode について紹介しています。 OpenCode とは OpenCode は、ターミナルベースのオープンソース AI コーディングエージェントです。75以上の LLM プロバイダーをサポートし、高度にカスタマイズ可能なインターフェースを提供します。 公式サイト: https://opencode.ai/ 公式ドキュメント: https://opencode.ai/docs GitHub: https://github.com/opencode-ai/opencode Claude Code から移行した理由 1. 日本語入力 Claude Code では、日本語入力の変換中に文字が横にずれる現象が頻繁に発生し、非常にストレスでした。 OpenCode では、この問題が発生せず日本語入力が自然に行えます。地味ですが一番自分にとって大きいメリットだったかもしれません。 2. 柔軟なキーバインド設定 OpenCode の最大の魅力は、キーバインドを自由にカスタマイズできる点です。 日本語入力 Claude Code では、日本語入力の変換中に文字が横にずれる現象が頻繁に発生し、非常にストレスでした。 OpenCode では、この問題が発生せず、日本語入力が自然に行えます。TUI(Terminal User Interface)の実装が優れており、IME との相性も良好です。 Emacs 風のキーバインドをサポート Emacs 風のキーバインドが設定出来る点は自分にとっては大きかったです。設定せずとも自然に Emacs 風にバインドされているキーもあります。 Ctrl-a: 行頭に移動 Ctrl-e: 行末に移動 Ctrl-h: 一文字削除 Ctrl-k: カーソル位置から行末まで削除 Ctrl-f, Ctrl-b: 前後に移動 "keybinds": { "input_backspace": "backspace,shift+backspace,ctrl+h", "input_delete_to_line_end": "ctrl+k" }, Enter と Ctrl-Enter を使い分け可能 特に便利なのが、改行とメッセージ送信を分離できる点です: ...

2025-12-28 · 4 分 · jedipunkz

Redirect for Infrastructure Page 35

このページは存在しないページネーション(page/35/)のためのリダイレクト設定です。 Infrastructure カテゴリの最初のページに自動的にリダイレクトされます。

2025-12-28 · 1 分 · jedipunkz