Goでパッケージのインポート方法がいろいろあって混乱したので整理してみました。
下の図に対応している章を見れば、インポート方法が分かるようになっています。
目次
- 1. 標準pkgをインポート
- 2. 自モジュール内のpkgをインポート
- 3. ネット上から取得したpkgをインポート
- 4. GOPATH配下のpkgをインポート
- 5. 任意のローカルフォルダ内のpkgをインポート
基本的にはモジュールモード
を想定していますが、4. GOPATH配下のpkgをインポートの章のみGOPATHモード
を使用します。環境変数でGO111MODULE=off
を設定してください。
1. 標準pkgをインポート
まずは標準パッケージをインポートします。
ディレクトリ構造とファイルの中身は以下の通りです。
- モジュールのフォルダ直下に
go.mod
ファイルを配置しています。 -
main.go
はmain
パッケージという特別なパッケージとなっており、モジュールの直下に配置することが出来ます。 - 標準pkgのインポートは
go.mod
ファイル内に何かを記述する必要はありません。
標準パッケージはimport "<pkg名>"
を記載するだけで読み込まれる。
module mymodule
go 1.18
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello World!")
}
実行例
D:\mymodule>go run main.go
Hello World!
D:\mymodule>go run main.go
Hello World!
2. 自モジュール内のpkgをインポート
ここでは自分自身のモジュール配下にあるパッケージのインポート方法について説明します。
ディレクトリ構造と各ファイルの中身は以下のようにしています。
- モジュールのフォルダ直下に
go.mod
ファイルを配置します。 -
main.go
はmain
パッケージという特別なパッケージとなっており、モジュールの直下に配置することが出来ます。 - パッケージはモジュールのサブフォルダとして作成します。なおパッケージ下に作成するファイル名は
mypkg.go
でなくhoge.go
などでも問題なく読みこまれます。 - 自モジュール内のパッケージをインポートする際は
go.mod
に何かを記述する必要はありません。
自モジュール内のパッケージはimport "<モジュール名>/<pkg名>"
と記載するだけで読み込まれる。
※ パッケージが複数階層になっている場合もimport "<モジュール名>/<フォルダ名>/<pkg名>"
のように記載すればよい。
module mymodule
go 1.18
package main
import (
"fmt"
// モジュールからのパスを記述
"mymodule/mypkg"
)
func main() {
fmt.Println("Hello World!")
mypkg.HelloFromMypkg()
}
package mypkg
import (
"fmt"
)
func HelloFromMypkg() {
fmt.Println("Hello from mypkg!")
}
実行例
D:\mymodule>go run main.go
Hello World!
Hello from mypkg!
3. ネット上から取得したpkgをインポート
ここではインターネット上のレポジトリから取得したパッケージのインポート方法を説明します。
ディレクトリ構造とファイルの中身は以下の通りです。
- モジュールのフォルダ直下に
go.mod
ファイルを配置しています。 -
main.go
はmain
パッケージという特別なパッケージとなっており、モジュールの直下に配置することが出来ます。 - import文にはパッケージのパスを記述します。。
- インターネット上から取得したパッケージは
go.mod
ファイル内にrequire
を記述する必要がありますが、自分自身で記述する必要はありません。go mod tidy
コマンドかgo get <pkg名>
コマンドを実行すると自動で追記されます。
インターネットから取得するパッケージはimport "<pkg名>"
を記載し、go.mod
ファイルにrequire
を記述すればよい。go.mod
は手動で書くのではなく基本的にはgo mod tidy
コマンドかgo get <pkg名>
コマンドを使う。
module mymodule
go 1.18
require github.com/go-ping/ping v1.1.0
require (
github.com/google/uuid v1.2.0 // indirect
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005 // indirect
)
package main
import (
"fmt"
// レポジトリ名を直接記述
"github.com/go-ping/ping"
)
func main() {
pinger, err := ping.NewPinger("www.google.com")
if err != nil {
panic(err)
}
pinger.SetPrivileged(true)
pinger.Count = 2
err = pinger.Run()
if err != nil {
panic(err)
}
fmt.Println(pinger.Statistics())
}
実行例
D:\mymodule>go run main.go
Hello World!
上記の例では、go mod tidy
またはgo get github.com/go-ping/ping
を実行すると、go.modファイルにrequireが自動で追記されます。
4. GOPATH配下のpkgをインポート
GOPATHを利用する際はモジュールモード
ではなくGOPATHモード
を使用します。環境変数でGO111MODULE=off
を設定してください。
ディレクトリ構成は以下のようにしています。
上記の注意書きにあるように、モジュールモードではなくGOPATHモードを利用するため、モジュールの概念は一旦忘れます(go.modなどはない)。
- インポート先のgoスクリプト(ここでは
main.go
)はmypkgフォルダ下に置いているが、作業フォルダはどこでも構いません。 - インポート対象のパッケージは
${GOPATH}/src
フォルダ下に配置します。 - モジュールモードではないため
go.mod
は不要です。
GOPATHモードを用いて、${GOPATH}配下のパッケージを読み込む際は対象のパッケージを${GOPATH}/src
下に配置し、import "<pkg名>"
を記載するだけでよい。
package main
import (
"fmt"
// パッケージ名を直接記述
"yourpkg"
)
func main() {
fmt.Println("Hello World!")
yourpkg.HelloFromYourpkg()
}
package yourpkg
import (
"fmt"
)
func HelloFromYourpkg() {
fmt.Println("Hello from yourpkg!")
}
実行例
D:\mypkg>go run main.go
Hello World!
Hello from yourpkg!
5. 任意のローカルフォルダ内のpkgをインポート
ここではローカル環境上の任意のフォルダ下にあるパッケージのインポート方法について説明します。
ディレクトリ構造と各ファイルの中身は以下のようにしています。
- モジュールのフォルダ直下には
go.mod
ファイルを配置します。※インポート対象であるyourpkgの親フォルダにもgo.mod
は必要です。go mod init
で作成するか、空のファイルを配置しておきます` -
main.go
はmain
パッケージという特別なパッケージとなっており、モジュールの直下に配置することが出来ます。 - パッケージはモジュールのサブフォルダとして作成します。なおパッケージ下に配置するファイル名は
mypkg.go
でなくhoge.go
などでも問題なく読みこまれます。 - 以下の例ではmymoduleとyourmoduleを同じ階層においていますが、インポート対象のyourmoduleの配置先は任意です。
-
go.mod
内のrequire
には<モジュール名>/<pkg名>
の形でパッケージへのパスを記述します。 -
go.mod
内のreplace
によりインポート対象のパッケージをローカルのディレクトリから取得させるようにします。
ローカルの任意のフォルダ上のパッケージはimport "<モジュール名>/<pkg名>"
でインポートし、go.mod
にはrequire
とreplace
を記載する。
module mymodule
go 1.18
require yourmodule v0.0.0
replace yourmodule => ../yourmodule
package main
import (
"fmt"
//モジュールからのパスでインポート
"yourmodule/yourpkg"
)
func main() {
fmt.Println("Hello World!")
yourpkg.HelloFromYourpkg()
}
module yourmodule
go 1.18
package yourpkg
import (
"fmt"
)
func HelloFromYourpkg() {
fmt.Println("Hello from yourpkg!")
}
実行例
D:\mymodule>go run main.go
Hello World!
Hello from yourpkg!
補足
ローカルに配置したパッケージをgithub.com
などから始めたいとき。
以下のようにパッケージ名と同じになるようにディレクトリを作成します
mymoduleのgo.mod
を以下のように記述すると、インターネット経由でgithub.com上のパッケージをインポートするようにローカル環境のパッケージをインポートすることが出来ます。
module mymodule
go 1.18
require github.com/yourmodule v0.0.0
replace github.com/yourmodule => ../github.com/yourmodule
package main
import (
"fmt"
//モジュールからのパスでインポート
"github.com/yourmodule/yourpkg"
)
func main() {
fmt.Println("Hello World!")
yourpkg.HelloFromYourpkg()
}