はじめに (対象読者・この記事でわかること)
この記事は、Go 言語で開発を始めた初心者から中級者、特に「godoc 上で標準ライブラリ以外の Example が cannot find package エラーになる」現象に遭遇した方を対象としています。
本稿を読むことで、以下ができるようになります。
- Go モジュール (
go.mod) の基本的な仕組みと作成方法が理解できる go getコマンドで外部パッケージを正しく取得し、実行可能にする手順が分かる- 実際にエラーが出たときのトラブルシューティング手順を身につけ、同様の問題を自力で解決できる
この問題は、Go 1.11 以降で導入されたモジュールシステムへの移行期に多く見受けられました。記事執筆のきっかけは、社内プロジェクトで同様のエラーが頻発し、メンバー全員が同じ手順で対処できるようにしたいという要望からです。
前提知識
この記事を読み進める上で、以下の知識があるとスムーズです。
- Go 言語の基本的な構文と
go run・go buildの使い方 - ターミナル(コマンドライン)での基本操作
- GitHub などのリモートリポジトリからコードを取得する概念
Goで外部パッケージを利用する際の課題と背景
Go の標準ライブラリは充実していますが、実務では外部パッケージを利用するケースがほとんどです。godoc.org(現 pkg.go.dev)で検索すると、数多くの Example が掲載されていますが、ローカル環境でそのまま go run しようとすると「cannot find package」というエラーが出ることがあります。
このエラーは主に次の二つの原因で発生します。
-
モジュール未設定
Go 1.11 以降はgo.modがプロジェクトのルートに存在しないと、外部パッケージの解決ができません。従来の$GOPATH/srcに依存した方式からモジュール方式への移行が完全に定着していない環境では、エラーメッセージが混在します。 -
パッケージ取得ミス
go getやgo installが正しく実行されていない、あるいはネットワーク制限(プロキシやファイアウォール)によりリモートリポジトリへアクセスできないケースです。結果として、ローカルにパッケージが存在せず、インポートが失敗します。
この二つの障壁を取り除くことで、Godoc の Example をそのままローカルで実行できるようになります。以下では、実際に手順を追いながら解決策を示します。
実践:go.mod と go get を使って Example パッケージを動かす手順
ステップ 1: プロジェクトディレクトリの作成と go.mod の初期化
まずは作業用ディレクトリを作成し、go.mod を生成します。go.mod はモジュール名と Go のバージョン情報を保持し、依存関係の管理を一元化します。
Bash# 作業ディレクトリ作成 mkdir -p ~/go-example/hello cd ~/go-example/hello # go.mod の初期化(モジュール名は任意のパス) go mod init example.com/hello
上記コマンドにより、次のような go.mod が生成されます。
Gomodule example.com/hello go 1.22
ステップ 2: 実行したい Example パッケージを取得
ここでは、github.com/google/uuid の Example をローカルで試すことにします。go get でパッケージを取得し、依存関係として go.mod に自動追加させます。
Bash# パッケージ取得 go get github.com/google/uuid@latest
取得が成功すると、go.mod と go.sum が更新され、次のようになります(抜粋)。
Gorequire github.com/google/uuid v1.3.0 // indirect
ステップ 3: Example コードを書いて実行
取得したパッケージの Example を参考に、最小のプログラムを書きます。main.go として保存してください。
Gopackage main import ( "fmt" "github.com/google/uuid" ) func main() { // Example: Generate a new UUID and print it id := uuid.New() fmt.Println("Generated UUID:", id) }
保存後、go run で実行します。
Bashgo run . # 出力例: # Generated UUID: 6f1e2a8b-3d5c-4b9a-9c5d-8f2d2c1e9b2a
ハマった点やエラー解決
エラー 1: cannot find package が出続ける
- 原因:
go.modが存在しない、またはGO111MODULE=offが設定されている - 対策: 確実に
go.modが作成されたディレクトリで作業し、export GO111MODULE=onでモジュールモードを有効化
エラー 2: go get がネットワークエラーで失敗
- 原因: 社内プロキシやファイアウォールが外部の GitHub へアクセスをブロック
- 対策: 環境変数
HTTPS_PROXYやGOPROXYを正しく設定
bash export GOPROXY=https://proxy.golang.org,direct # 社内プロキシが必要なら export HTTPS_PROXY=http://proxy.example.com:8080
エラー 3: go run . で module requires Go 1.xx と出る
- 原因:
go.modに記載された Go バージョンがインストールされている Go のバージョンと合わない - 対策:
go.modのgo行を実際に使用しているバージョンに合わせるか、ローカルの Go バージョンをアップデート
解決策のまとめ
- 必ず go.mod を作成 –
go mod initでプロジェクトをモジュール化 - 正しい go get の実行 – パッケージ名とバージョンを明示し、
GOPROXYを設定 - 環境変数でモジュールモードを保証 –
GO111MODULE=on、GOPROXY、HTTPS_PROXY - エラーメッセージを読み解く –
cannot find packageはモジュール未設定、network errorはプロキシ・ファイアウォールが疑い対象
これらを順に実行すれば、godoc の Example をローカルで問題なく動作させることができます。
まとめ
本記事では、Go のモジュールシステムを利用して「godoc の Example が cannot find package エラーになる」問題を体系的に解決する手順を紹介しました。
- go.mod の初期化でプロジェクトをモジュール化し、依存関係を明示的に管理
- go getで対象パッケージを取得し、
go.modとgo.sumを自動更新 - 環境変数の設定でネットワークやモジュールモードの障壁を排除
- トラブルシューティングでよくあるエラーと対処法を提示
この記事を通して、読者は外部パッケージの取得から実行までの一連のフローを自力で完結できるようになります。次回は、複数パッケージの依存関係を最適化する go mod tidy や、プライベートリポジトリの認証設定に関する記事を執筆予定です。
参考資料
- Go Modules Reference (公式ドキュメント)
- pkg.go.dev – Go Package Documentation
- GitHub – google/uuid
- Effective Go – Packages and Modules
