Go言語を習得する過程で自分で学んだこと・参考情報サイトなどをまとめていきます
すなわち本内容は完成記事ではなく学習の過程で記事を加筆していくつもりです。
割と個人の覚書きの性質の強い記事ではありますが、ひょっとしたら他の「これからGoをやるぞ!」と思う人の助けになることがあるかもしれないので公開します。
各セクションについて、ボリュームが膨らんできてここに載せておくには文章量が多いな…と感じてきたらその部分は単独記事として独立化させていく予定です。
基礎:まずはこのあたりから勉強
プログラミング言語Go完全入門
このドキュメントは、仕様を言葉で定義してくれないので、サンプルを見て「わかれ」という書き方なので個人的にはあまり好みじゃないのですが、公開時期が2019年と比較的新しく、これが分かりやすいとおススメしている方もいるので紹介します。質問ができるコミュニティへの案内があるのはありがたいですね。
公式ドキュメント
公式ドキュメントの言語仕様のページは英語かつ書き方が人間に優しくない形式文法っぽい感じなので読むのがめんどい…。まあ厳密に正確な定義をすべき公式ドキュメントだから「この仕様どうなってたっけ?の最終的な答え合わせ」がしたい時にはこれを参照するのがいいんでしょうね。(ただ、初心者が一番最初に読むものではないと思う)
Tour of Go は色んな人にオススメされるのでやっておいたほうがよさそう?(まだ筆者はあまり進められていないので、進めたら感想を追記します)
はじめてのGo
このドキュメントが個人的に好み(日本語で読める。ある程度厳密な仕様がわかる)。デメリットは執筆時期が2015年とちょっと古めなことか。Goは割と活発にバージョンアップしている言語みたいなのでちょっと前の古いテキストだと最新仕様とズレが大きくなるのが心配かも。
→ (2023/02/11追記)GOPATH使う前提でgo modが標準になる以前の教え方なのでこれを読みながらGoの勉強をするのは現在ちょっと辛くなってきた…別の資料をあたるほうが良さそう…
Go言語の初心者が見ると幸せになれる場所
勉強が軌道に乗り出したあたりで、より実践的な情報、好ましい書き方を身につけるために読むとよさそう
Go強化月間~開発する上で知っておくべき知見を共有しよう~
Goを学ぶときにつまずきやすいポイントFAQ
Go言語特有のクセについて説明してくれている。一度目を通しておいたほうが良さげ
「Go初心者が気を付けること」の解説
初心者がハマりやすいポイント、他言語では適切だがGoでは不適切なコーディングなどが書かれている
Go言語は沼
こちらも初心者がハマりやすいポイントが列挙されています
新規プロジェクトの作り方などが載っています
実行環境
MacでGoをインストールする場合
MacでHomebrewからgoをインストールした場合、.zshrcにはどう設定すべきか、どこにPATHを通すべきかなど、分からなくなった時はこの記事参照。
↓
go install
でインストールしたバイナリや、自分でgo build
した時のバイナリが保存される場所であるGOPATH
はOSで上書きすることもできるが、デフォルトで~/go
が設定されているから変える必要がなければ特に設定不要。
GOROOTも同様の理由で特に設定不要。
# GOの環境変数確認方法
$ go env GOPATH
=> /Users/USERNAME/go
$ go env GOROOT
=> (goがインストールされている場所)
↓
PATHはhomebrewでインストールしただけだと自動で設定されないようなので
GOPATHに置かれるバイナリをコマンドラインで実行したければ、PATHを通す必要がある
その場合は、~/.zshrc
に下記の通り記載
# .zshrc
export PATH=$PATH:$(go env GOPATH)/bin
古いコードを動かしたい場合
→ バグ原因調査で、ソフトの過去バージョンの動作を確認したいことがよくあるので、この記事が参考になりそう
その他実行環境関係の記事
コンパイルや実行の手順
# main.go をコンパイルする
go build main.go
# コンパイルの結果作られた実行ファイル(バイナリ)を実行すればプログラムが起動する
./main
# 実行ファイル名を指定することもできる
go build -o build-name main.go
# -> ./build-name という実行ファイルが出来る
# コンパイルから実行までを一つのコマンド'run'で実行することもできる
go run main.go
もっと詳しく知りたい場合は公式ドキュメントを参照
go build
go run
環境変数GOPATHとは
-> インストールしたGoのバイナリや、外部のパッケージを配置するためのディレクトリ。GOPATH通した場所においたパッケージはimport可能になる
# GOPATHの値確認
printenv GOPATH
# GOPATHの場所へ移動
cd $GOPATH
# GOPATH直下のディレクトリ構成
ls $GOPATH
# -> bin pkg
↑ ブラウザで動く実行環境。さっと動作確認するのにオススメ。
モジュールとかパッケージとか
公式ドキュメントではこの辺り
A module is a collection of packages that are released, versioned, and distributed together.
「モジュールとは、一緒にリリースされ、バージョン管理され、配布されるパッケージの集まりである」と書かれているので、包含関係としては「あるモジュールには、1個以上のパッケージが含まれる」ということになる。
最近のGoでは、go mod
を使うやり方が標準になっており、それ以前のGOPATH
を使うやり方で教えている文献は参考にしないほうがいいかも…(もしくは、そのギャップを脳内で補正できるようになってから読むべき)
ここを読むと、モジュールの仕組みはなんとなく分かってきた。
上記ページを参考にするときの注意点として
コマンドの意味 > 試してみよう
で、go get
を実行する前にhello.go
と同一ディレクトリで
go mod init hoge
を実行して go.mod を作成しておかないとその後の指示に従っても記事通りにコードが動作しない。
※ go get
してもgo.mod
は作られないためである
※ が、GOPATHにgo-cmpのパッケージが追加されているのでimport は有効になっているし、go run すると実行はできる
※ IDEはhello.go
においてcould not import github.com/google/go-cmp/cmp
というエラーを吐いていた
go get と go install
その他パッケージ、モジュールについての各種解説(整理中)
基礎文法
データ構造
interface
型変換についても触れられた資料
構造体
初期化
タグでメタ情報を構造体フィールドに付与
配列
データ構造の操作
ループ(range)
日付・時刻型
関数
後日記載予定
型アサーション
<変数>が<型>であるかどうかをチェックする
value, ok := <変数>.(<型>)
ライブラリ
Echo
Webフレームワーク
WebAPIが作れる
Gorm
公式ドキュメント
公式ドキュメント(日)
ORマッパー
簡単に言うとGoでDBのデータ読み書きをするコードを書くためのライブラリ。
クエリを発行するには↓みたいな書き方をする
GormでSQLインジェクションの脆弱性を回避するための注意
↑ 後で読む
Wire
DI(Dependency Injection):依存性の注入をするためのライブラリ
上記ページを参考に学習する際の注意
フローを把握する > DI用の関数を生成する
の手順をそのまま実行するとwire
コマンド実行したら
could not import github.com/google/wire (invalid package name: "")
というエラーが発生した
この場合、wire
を実行する前に下記の方法でgo.modを作成しておく
$ go mod init hello
$ go mod tidy
$ cat go.mod
module hello
go 1.17
require github.com/google/wire v0.5.0
こうすると(ローカルに?)wireがインストールされるので
コマンドwire
が実行可能になる
テスト
Go の標準テストパッケージ testing の使い方
- テストコードは {{hoge}}_test.go というファイル名にする
- テスト関数は Test{{Fuga}} という名前にし、
t *testing.T
という唯一つの引数をとる
テスト作成方法
下記記事でテストの自動生成について記載されています
テスト実行方法
go test
# → {{hoge}}_test.go ファイルが存在するディレクトリで`go test`を実行する(引数不要)だけでテストが実行される
go test -run Piyo
# → Piyoという名前を含むテスト関数が実行される (例: TestPiyoFuga)
go test -v
# → テスト内でPrintlnした時にデフォルトでは標準出力に出ないが、-vをつけると出てくるようになる
go test -count=1
# テスト結果がキャッシュされなくなる
なぜこれでキャッシュされなくなるのか、詳しくはこちら↓
メモ・未分類
静的解析
他言語との違いで戸惑ったこと
↑ f文で初期化式を入れられるとか、関数の多値返却とか、今までの言語で自分がみたことのなかったような書き方に戸惑った話
なお、X.(T) は型アサーションである
UberのGoプログラミングコーディング規約
例外処理
↑ 今読んでる