updated on 2020-12-15
パッケージ
mainパッケージ
標準パッケージ
サードパーティパッケージ
他のパッケージの機能を使う
パッケージをインポートしてできること
以下のように、標準パッケージとサードパーティパッケージは空行を挟んで分けることが多い
import ( "context" "fmt" "github.com/tenntenn/greeting" )
相対パスでのインポート
非推奨のやり方
import "./model"
絶対パスでのインポート
import "github.com/tenntenn/greeting"
単一行でのインポート
import "fmt" import "string"
グループ化を使ったインポート
import ( "fmt" "string" )
ピリオドインポート
import ( . "fmt" "string" )
通常、「fmt.Println("hello world")
」と書くところをドットをつけてインポートすると「Println("hello world")
」と書くことができます。
つまり、ドット付きインポートはパッケージの関数を呼び出す際にパッケージ名を省略して書くことができます。
エイリアスインポート
import ( f "fmt" )
このような書き方でパッケージ名にエイリアスをつけることができます。
上の場合、「fmt.Println("hello world")
」のかわりに「f.Println("hello world")
」とエイリアスを用いて書くことができます。
ブランク(_)インポート
import ( "database/sql" _ "github.com/ziutek/mymysql/godrv" )
パッケージをインポートするだけで、パッケージの中の関数を直接使うわけではなく、このパッケージの中にあるinit関数をコールする。
インポート宣言は、インポート「する側」と「される側」の依存関係を宣言します。自分自身のパッケージをインポートすること、またはインポートしたパッケージ内でエクスポートされている識別子を一切参照しないことは誤った使い方です。インポートによる副作用(初期化)のためだけにパッケージをインポートするときは、パッケージ名としてブランク識別子を使う。
別名をつける
import ( "sync" mysync "github.com/tenntenn/sync" // syncパッケージと名前が衝突しているので、エイリアスを使う greeting "github.com/tenntenn/greeting/v2" // インポートパスとパッケージ名が一致していないので、エイリアスを使う ) func main() { fmt.Println(greeting.Do()) }
エクスポート
ライブラリ
以下の例で、Piという識別子はmathパッケージからエクスポートされている
package main import ( "fmt" "math" ) func main() { fmt.Println(math.Pi) }
(コンソール出力)
3.141592653589793
■ GOPATHとは?
確認方法
$ go env GOPATH
$GOPATH
├── bin (ビルドされた実行可能ファイルが入る)
│ └── fuga
├── pkg
│ └── darwin_amd64 (ビルドされたパッケージが入る)
│ └── hoge.a
└── src
├── github.com
│ ├── YourUsernameOfGihub (githubのユーザー名ディレクトリにgithubのプロジェクトを普通管理する)
│ │ ├── github_cloned_repository (git cloneしたレポジトリ)
│ ├── davecgh (go getコマンドで取得したサードパーティ)
│ ├── pmezard (go getコマンドで取得したサードパーティ)
│ └── stretchr (go getコマンドで取得したサードパーティ)
├── fuga
│ └── main.go (実行可能なgoのコード)
└── hoge
└── hoge.go (ライブラリのgoのコード)
スコープ
ブロック
エクスポートされた識別子
Goのスコープ
スコープは4種類
スコープ | |
---|---|
universeブロック | 事前宣言された型 [ bool byte complex64 complex128 error float32 float64 int int8 int16 int32 int64 rune string uint uint8 uint16 uint32 uint64 uintptr ] 定数[ true false iota ] ゼロ値[ nil ] 関数 [ append cap close complex copy delete imag len make new panic print println real recover ] |
packageブロック | トップレベル関数外で宣言された定数、型、変数、関数(メソッド除く) |
fileブロック | インポートされたパッケージのパッケージ名 |
localブロック | メソッドのレシーバ、関数の引数、戻り値の変数 |
init
関数はパッケージの初期化時に呼び出される関数 (パッケージの初期化が先である)
main
パッケージに書くとmain
関数より先に実行されるfmtパッケージが初期化された後に、initが呼び出されて、その後mainが呼び出されている
package main import "fmt" var msg = message() func message() string { return "Hello" } func init() { fmt.Print(msg) } func main() { fmt.Println(", playground") }
(コンソール出力)
Hello, playground
依存パッケージの初期化
各パッケージの初期化
go getコマンド
Goのライブラリなどを取得するコマンド
依存するライブラリも一緒に取得してくれる
指定した場所からダウンロード&インストールしてくれる
一度取得したものは2度取得しない
-uオプションでダウンロードを強制する
$ go get github.com/tenntenn/greeting $ ls $GOPATH/src/github.com/tenntenn/greeting README.md greeting.go
実際に使ってみる
package main import ( "fmt" "time" greeting "github.com/tenntenn/greeting/v2" ) func main() { t := time.Now() fmt.Printf("現在時刻: %v あいさつ: %s\n", t, greeting.Do(t)) }
(コンソール出力)
現在時刻: 2020-12-06 16:31:38.257042 +0900 JST m=+0.000115566 あいさつ: こんにち
godoc
godoc.org
$ godoc -http=:6060 (ipは任意)
パッケージまでのパスが $GOPATH/src/sample 場合、
http://localhost:6060/pkg/sample でアクセス
Go 1.11よりModules(vgo)という仕組みが標準装備になっている
module-aware mode
と呼ぶらしい。$GOPATH/src
にソースコードが置かれない($GOPATH/src
に置くためには、GO111MODULE=off go get ライブラリ という風にしなければならない)go.mod
が存在し、$GOPATH内であればmodulesを使うようになる。$ go mod init # カレントディレクトリに新しいモジュールを初期化し、go.modが作成される
hello.goを作ってみる
package main import ( "fmt" "rsc.io/quote" ) func main() { fmt.Println(quote.Opt()) }
ビルドすると、自動でライブラリ "rsc.io/quote" とその依存ファイルをダウンロードしてビルドしてくれる!
ビルドした際に、go.modにはファイルを実行するのに必要なモジュールが記述され、go.sumにはモジュールのバージョンが記述される。
ライブラリは$GOPATH/pkg/mod
に保存される
go installすると$GOPATH/bin
に保存される
$ go build go: finding module for package rsc.io/quote go: downloading rsc.io/quote v1.5.2 go: found rsc.io/quote in rsc.io/quote v1.5.2 go: downloading rsc.io/sampler v1.3.0 go: downloading golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
Go Modules ではプロジェクトを GOPATH の外に置けるが、ライブラリのキャッシュや go install のコピー先として GOPATH (デフォルトで ~/go) が使われる。
ライブラリのバージョンの決め方
一旦必要なバージョンが go.mod に記載されると、それ以降は go コマンドは勝手にライブラリのバージョンを上げない。これでバイナリ作成時の依存バージョンを特定出来る
モジュールのアップデート
$ go get -u # go.modファイルが更新される
モジュールの削除
go get
で明示的にパッケージをインストールすると go.mod に使わないライブラリのカスが貯まるので、以下のコマンドで使うやつだけに整理する。
$ go mod tidy # 足りないモジュールを追加し、使用されていないモジュールを削除する