実用go言語
1章 「Goらしさ」に触れる
1.2.1
数値型リテラルの範囲に限界はない
1.2.3
Goのconstはコンパイル時に確定している普遍の値, よってTypeScriptなどで使用できるスライス等はconstに格納できない
1.3.1
iotaという定数がある, 列挙型を実現するのに有用
1.4.2
panicはほぼ使わない
1.4.4
Goは複数の値を返せ, 最後の値でerrorを返す. try exceptみたいに例外機構があると, ネストが深くなったり例外処理がロジックと密結合して良くない.
1.6
Goにはkeyword引数やoption引数がない. これらはどうGoの中で実現するか?
1. コンストラクタを複数作る
2. オプション構造体を渡す (まずはおすすめ)
3. fluent option pattern
4. functional option pattern
1.8
メモリ起因のパフォーマンス低下の解消
Goでパフォーマンスが低下するのは, たいていmapやスライスのメモリ確保 (OSがswapやOOMキラーを発動し動的確保するから)
対処法として, makeを使いcapあるいはlenを大きくとって一括でメモリを確保しておく
1.8.3
deferの後の処理(Closeなど)でエラーが発生することがあるので, deferの後には無名関数を書き, その中でerrへの代入を行うと呼び出し元でerrのチェックを行える.
1.11
go fmtにはオプションもなく, パッケージ管理も公式で用意され, コードなどに差が出にくい仕様となっている
たしかにgoにはpyenvやrbenvのように処理系のバージョンを管理するシステムもないと聞いた, シンプルだ
読みやすさ > 書きやすさ重視の言語と言えるね
2章 定義型
2.1.1
Goにおいて型は一級市民ではない
Pythonだと, intとかclass名そのものが値を持っているという話か?
メソッドは型に紐づく. インスタンスがなくてもメソッドは呼べる
2.2.3
コンストラクタではなくファクトリー関数でインスタンスを作る
2.3.4
関数でなく, レシーバーを用いたメソッドを使おう
3章 構造体
3.1
typeキーワードを使わなくても, その場で使う構造体を宣言できる
ポインターは自動的にデリファレンスされるので, (*book).Titleしなくてもbook.Titleで良い
3.2
インスタンスの作成にはいくつか方法があるが, それらの方法をラップしたファクトリー関数が用いられることが多い
入力値のバリデーションやユースケースごとのファクトリーを書けるので便利
3.3
Goにクラスはないが, メソッドを持った構造体は開発の中で近い立ち位置となる
レシーバーは値とポインタの2種類あるが, 値型だとフィールドの変更はされない
関数は一級市民
3.4
構造体の埋め込みにより, 継承のようなことができる(内部の構造体に対して定義されているメソッドを使用できる)
3.5
Goではタグを用いて構造体にメタデータを埋め込む
json, validate, gormなどのタグを付けておけば, フロントからのjsonをオブジェクトにしてvalidateし, ormでDBにpushできる
リフレクションは, プログラム中でプログラムを事故言及すること
ex. eval("Foo().hello()") in python
reflect.ValueOf(i).Kind()でiのクラスをstrとしてとれる(reflect.Int)
3.9
構造体の埋め込みは継承のように見えるが違う
ちょっと便利なHas A関係である
6章 パッケージ, モジュール
この章は実際のrepo見ながら勉強するのが良さそう
helpfulな記事達
Pythonはファイルがモジュールで, ディレクトリがパッケージだが, Goは逆である(?)
6.1.1
パッケージ=フォルダにすべてのソースコードが属す
フォルダ内のファイルは基本的に同じパッケージでないといけない(package sample)
例外は<package>_testのみ
フォルダの位置や深さについては, プログラム上で上下関係や親子関係はない. 親packageは子packageとは独立しているとも言える
6.1.4
モジュールにはgo.modが含まれる. 外部パッケージを利用するとgo.sumも作られる.
モジュールはライブラリ配布の単位でもある. 公開する場合はgithub.com/hogehoge/projectみたいになる.
6.1.6
モジュールのimportに相対パスは使用できない. 常にgithub.com/hogehoge/project/subdirのように指定する.
6.2.1
go getでモジュール追加, go mod tidyえ不要ライブラリの削除
6.3
プロジェクトのライフサイクル
go mod initでモジュールを作成
git tag v1.0.0とがでタグ付けしてpushすればgo getで取得できるようになる
6.4
プロジェクトのモジュール内のパッケージ構成
ライブラリとして配布するのではなく, 実行ファイルを含める場合は, ルートにcmdフォルダを作り, その下にコマンド名と同一のフォルダ名を作るのが一般的
6.4.2
循環参照に奈良ないようパッケージを複数に分割するにはいくつか戦略がある
1. 共通要素のパッケージを作りそこに依存先を集中させる
2. ルートパッケージのロジックを移動し, ルートパッケージを共通要素置き場とする
3. 共通部分を持たない末端のロジックを子パッケージとして切り出す
6.4.4
stringerとかの開発時に使うGo製ツールを管理するときは, tools.go patternを使うと良い.
cat tools.go | awk ...みたいなのをMakefileに登録しておく
7章 整備
7.2
Goは1.xの間はソースコードの互換性が保たれる
7.7.1
.PHONY cleanと書くことで, cleanという名前のファイルがあったときにも適切にコマンド実行されるようになっている
8章 様々なデータフォーマット