世界を動かす技術を、日本語で。

Goを使おう

2026年5月8日原文(blainsmith.com)

概要

Goは シンプルさ堅牢性 を重視した言語。 依存関係の問題複雑なデプロイ から解放される。 標準ライブラリだけで フル機能のWebアプリ が実現可能。 ツールチェーン が一体化しており、運用も容易。 「 退屈」こそがGoの最大の強み。

Goは「退屈」こそが正義

  • Go2秒でコンパイル単一バイナリ でデプロイ可能
  • npm の依存関係トラブルや ビルドツールの乱立 からの解放
  • Node.jsRailsRust の過剰設計へのアンチテーゼ
  • HTML が進化しつつも本質を維持してきたのと同様の思想

言語仕様のシンプルさ

  • デコレーターメタクラスマクロトレイト などの複雑な抽象化を排除
  • structfunctioninterfacegoroutinechannel のみで構成
  • 言語仕様 は昼休みに読めるレベルの分量
  • gofmt による自動整形で コードスタイルの統一
  • 抽象化の暴走 を防ぎ、 可読性と保守性 を担保

標準ライブラリが最強のフレームワーク

  • 標準ライブラリ だけで Webアプリ が完結
    • embed でテンプレートをバイナリ内に埋め込み
    • html/template でサーバサイドレンダリング
    • net/http でWebサーバ機能
  • WebpackVitedev server巨大なnode_modules 不要
  • database/sql でDB接続、 encoding/json でJSON処理
  • net/http はクライアント機能も提供
  • goroutine で並列処理、 go test でテスト、 pprof でプロファイリング

標準ライブラリの奥深さ

  • io.Readerio.Writer という2つのインターフェイスがエコシステムの基盤
  • context.Context でリクエスト単位のキャンセルやタイムアウト管理
  • encoding/json/xml/csv/binary は同じパターンで学習コスト低減

泣かない並行処理

  • goroutine はスレッドではなく、2KB程度で数十万単位の同時実行が可能
  • channel で型安全な通信と同期
  • sync.Mutex で共有状態の排他制御、 race detector で競合検知
  • async/await や複雑なコールバック不要

実践的なCRUD例

  • Postgres 接続、 HTMLレンダリングHTTPハンドラ を1画面で完結
  • リクエストのcontext をDBクエリに渡すことで安全なキャンセル処理
  • ORM やDIコンテナ、サービス層、抽象クラス不要
  • トップダウンで読める 明快な構造

依存管理の安心感

  • go mod init でプロジェクト初期化
  • go.modgo.sum のみで依存管理
  • node_moduleslockfileの不整合peerDependencies 問題なし
  • go mod vendor でオフラインビルドも容易
  • セキュリティ 面でも信頼性抜群

ツールチェーンの一体化

  • gofmt でコードフォーマット、 go vet で静的解析
  • go test でテスト、 -race で競合検知、 -bench でベンチマーク、 -cover でカバレッジ
  • pprof で本番環境のプロファイリングも簡単
  • 全て標準搭載、サードパーティや設定ファイル不要

デプロイは「コピー」だけ

  • バイナリをビルドしてサーバにコピーし、実行するだけ
  • DockerfileKubernetesHelm 不要
  • 12MBの静的バイナリ20行のsystemdユニットファイル で本番運用
  • Docker が必要な場合も FROM scratch でOK

他フレームワークとの比較

  • Rails は複雑なデプロイ手順と儀式
  • Django は独自ORMやミドルウェア学習が必須
  • Express は脆弱なnpmエコシステム依存
  • Next.js は仕様変更が頻繁で不安定
  • Goバイナリ は数年後も動き続ける信頼性

モノリス推奨、マイクロサービス不要

  • 1バイナリ、1Postgres、必要ならRedis で十分
  • HTMLとAPI を同じポートで提供
  • VPS1台 で1万RPSも余裕
  • 本当に分割が必要なら、パッケージをリポジトリ分割するだけ

ジェネリクス・エラーハンドリングについて

  • if err != nil が特徴であり、例外隠蔽を防ぐ
  • ジェネリクス も1.18で導入済み、必要な時だけ使えば良い

まとめ:「退屈」こそ最適解

  • フレームワーク不要マイクロサービス不要Rustリライト不要
  • go mod initmain.go 作成、 テンプレート埋め込みビルドしてデプロイ
  • 退屈な選択 が最良の選択
  • Go は最初から最後まで現場主義の「出荷できる」言語

Hackerたちの意見

よくGoは「より良い」Pythonだと思う。学びやすくて使いやすいし、パフォーマンスもいい。モジュールシステムやパッケージマネージャーも少しスッキリしてるしね。(フレームベイトごめん)でも、似たようなユースケースをどれだけカバーできるのかな?GoはDevOpsやウェブバックエンドには最適だけど、AIやデータサイエンスはどうなんだろう?

GoがCと同じくらいPythonとインターフェースできたら、もっと使うのに。でも、もっと多くのものと統合できる遅い言語を使ってる。例えば、AIがPythonに集中している理由の一つは、CUDAが基本的にCエコシステムの一部だから(つまりビルドシステム)。

以前はPythonでデータエンジニアリングをたくさんやってたけど、今は主にGoでいろんなエンジニアリングをしてる。Goのデータエコシステムは非常に限られてるよ。広くサポートされているデータフレームライブラリ(古いpandasや新しいRustで書かれたpolarsなど)がないし。データサイエンスライブラリもほとんどないし、いくつかの良い生成AIライブラリはあるけど、Pythonの仲間たちほど人気じゃない。今やってる仕事のほとんどはストリーミングデータと非常に小さなバッチ処理。これにはGoが素晴らしい。JSONを変換して、他のデータと結合してデータベースに書き込むのにデータフレームは必要ない。ロジックを書いて、速く動かせばいいだけだから。Goではすごく簡単だよ。

Goはシンプルなアプリケーション、特にインターネットに接続するバックエンドにはいいと思う。NodeやJS、TSよりも好きだな。多くのプロジェクトはJavaや他の言語で書くよりGoで書いた方が良かったと思う。万能ではないけど、足を引っ張ることも簡単にできちゃう。簡単なことは簡単だけど、難しいことは本当に難しい。Rustの方がちょっと好きだけど、書き直すことはない。最初に選ぶのはRust。好みだけど、好きにやってくれ。

Goが大好き。でも、ウェブ開発には.NETの方が好き。バイナリにコンパイルできるし、ライブラリやパッケージのエコシステムも素晴らしい。Goの標準ライブラリが使えるなら最高だけど(多くの場合は使えるけど)、非標準ライブラリを使う必要が出てくると、制限が出てくることもある。例えば、Goでデータベースを使ったフルプロダクションのウェブアプリを作るには、素晴らしいマイグレーションツールがない。もちろん良いサードパーティのライブラリもあるけど、.NETのEFCoreと比べると、そこまで近くはない。今は.NETがあって、その後にGo。もちろん、ウェブじゃないことをやるときはGoも使うけどね。

Goと.NETを比べるのは、ホンダと車輪のついた空母を比べるようなもんだよ。

"バイナリにコンパイルされる" っていうのは、あんまり役に立たない基準だよ。Goが勝ってる基準は「単一の、完全に自己完結したバイナリにコンパイルされる」ってこと。つまり、libcや外部のランタイムに依存しないってことだよね。.NETについてはそう言えないし、ほとんどの他のプログラミング言語についても言えない。これは非常に珍しいことなんだ。.NETがバイナリパッケージ形式を使ってるっていうのは、まあ、だから何?って感じだね。

これにはたくさんのメリットがあると思う。Goはプログラミング界のホンダオデッセイミニバンだと呼んでる。特別に何かが得意ってわけじゃないけど、たくさんのことをシンプルで信頼性のある方法でうまくやってくれる。特にReactのフロントエンドに対するバックエンドにはぴったり。でも、書くのは結構面倒で、足を引っ張る要素も多い。特にNullの扱い。どうやっても他の言語より悪化させてしまったみたい。

Nilawayのリンター最高!

Goのヌル処理が他の言語よりも悪い理由って何だろう?

Goは好きだけど、愛せない小さな理由がたくさんある。例えば、enum。JavaやKotlinでenumを使うと、すごく便利なんだ。Stringとの変換も簡単だし、型安全性も…ある。Goでもできるけど、表現したいenumのタイプごとにハックしないといけない。言語にenumがないから、一度に言語を頭に入れておくのは簡単だけど、自分が書いているソフトウェアを頭に入れておくのは難しくなる。「このenum」はあの「enum」と同じ?コードを読まないとわからない。でもGoはたくさんのことが得意だよ。コンパイル時間、静的バイナリ、リソースがそのバイナリに組み込まれてる、実行速度…好きなところがたくさんある。

くだらないジェネリクスの代わりに、列挙型を追加してほしかったな。

Hacker Newsで議論の続きを見る