LoginSignup
14
17

More than 1 year has passed since last update.

Goにおけるパッケージのインポート方法いろいろ~ローカル環境のパッケージをインポートしたい~

Last updated at Posted at 2022-07-24

Goでパッケージのインポート方法がいろいろあって混乱したので整理してみました。
下の図に対応している章を見れば、インポート方法が分かるようになっています。

flow.png

目次

基本的にはモジュールモードを想定していますが、4. GOPATH配下のpkgをインポートの章のみGOPATHモードを使用します。環境変数でGO111MODULE=offを設定してください。

1. 標準pkgをインポート

まずは標準パッケージをインポートします。
ディレクトリ構造とファイルの中身は以下の通りです。

  • モジュールのフォルダ直下にgo.modファイルを配置しています。
  • main.gomainパッケージという特別なパッケージとなっており、モジュールの直下に配置することが出来ます。
  • 標準pkgのインポートはgo.modファイル内に何かを記述する必要はありません。

標準パッケージはimport "<pkg名>"を記載するだけで読み込まれる。

1_directory.png

go.mod
module mymodule

go 1.18
main.go
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.gomainパッケージという特別なパッケージとなっており、モジュールの直下に配置することが出来ます。
  • パッケージはモジュールのサブフォルダとして作成します。なおパッケージ下に作成するファイル名はmypkg.goでなくhoge.goなどでも問題なく読みこまれます。
  • 自モジュール内のパッケージをインポートする際はgo.modに何かを記述する必要はありません。

自モジュール内のパッケージはimport "<モジュール名>/<pkg名>"と記載するだけで読み込まれる。
※ パッケージが複数階層になっている場合もimport "<モジュール名>/<フォルダ名>/<pkg名>"のように記載すればよい。

2_directory.png

go.mod
module mymodule

go 1.18
main.go
package main

import (
	"fmt"
    // モジュールからのパスを記述
	"mymodule/mypkg"
)

func main() {
	fmt.Println("Hello World!")
	mypkg.HelloFromMypkg()
}
mypkg.go
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.gomainパッケージという特別なパッケージとなっており、モジュールの直下に配置することが出来ます。
  • import文にはパッケージのパスを記述します。。
  • インターネット上から取得したパッケージはgo.modファイル内にrequireを記述する必要がありますが、自分自身で記述する必要はありません。go mod tidyコマンドかgo get <pkg名>コマンドを実行すると自動で追記されます。

インターネットから取得するパッケージはimport "<pkg名>"を記載し、go.modファイルにrequireを記述すればよい。go.modは手動で書くのではなく基本的にはgo mod tidyコマンドかgo get <pkg名>コマンドを使う。

1_directory.png

go.mod
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
)
main.go
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名>"を記載するだけでよい。

4_directory.png

main.go
package main

import (
	"fmt"
	// パッケージ名を直接記述
	"yourpkg"
)

func main() {
	fmt.Println("Hello World!")
	yourpkg.HelloFromYourpkg()
}
yourpkg.go
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.gomainパッケージという特別なパッケージとなっており、モジュールの直下に配置することが出来ます。
  • パッケージはモジュールのサブフォルダとして作成します。なおパッケージ下に配置するファイル名はmypkg.goでなくhoge.goなどでも問題なく読みこまれます。
  • 以下の例ではmymoduleとyourmoduleを同じ階層においていますが、インポート対象のyourmoduleの配置先は任意です。
  • go.mod内のrequireには<モジュール名>/<pkg名>の形でパッケージへのパスを記述します。
  • go.mod内のreplaceによりインポート対象のパッケージをローカルのディレクトリから取得させるようにします。

ローカルの任意のフォルダ上のパッケージはimport "<モジュール名>/<pkg名>"でインポートし、go.modにはrequirereplaceを記載する。

5_directory.png

mymodule/go.mod
module mymodule

go 1.18

require yourmodule v0.0.0

replace yourmodule => ../yourmodule
main.go
package main

import (
	"fmt"
	//モジュールからのパスでインポート
	"yourmodule/yourpkg"
)

func main() {
	fmt.Println("Hello World!")
	yourpkg.HelloFromYourpkg()
}
yourmodule/go.mod
module yourmodule

go 1.18
yourpkg.go
package yourpkg

import (
	"fmt"
)

func HelloFromYourpkg() {
	fmt.Println("Hello from yourpkg!")
}
実行例
実行例
D:\mymodule>go run main.go
Hello World!
Hello from yourpkg!

補足

ローカルに配置したパッケージをgithub.comなどから始めたいとき。
以下のようにパッケージ名と同じになるようにディレクトリを作成します

h_directory.png

mymoduleのgo.modを以下のように記述すると、インターネット経由でgithub.com上のパッケージをインポートするようにローカル環境のパッケージをインポートすることが出来ます。

mymodule/go.mod
module mymodule

go 1.18

require github.com/yourmodule v0.0.0

replace github.com/yourmodule => ../github.com/yourmodule
main.go
package main

import (
	"fmt"
	//モジュールからのパスでインポート
	"github.com/yourmodule/yourpkg"
)

func main() {
	fmt.Println("Hello World!")
	yourpkg.HelloFromYourpkg()
}

参考資料

14
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
17