Go読書会 #4 がランサーズ株式会社で行われたので進捗と技術的なメモ書きを書いておきます。読書会の内容はプログラミング言語Goを冒頭から皆で読み進めていくというものです。
進捗した内容
- 2章 プログラムの構造
- 2.3 変数
- 2.3.2 ポインタ
- 2.3.3 new関数
- 2.3.4 変数の生存期間
- 2.4 代入
- 2.4.1 タプル代入
- 2.4.2 代入可能性
- 2.5 型宣言
- 2.6 パッケージとファイル
- 2.6.1 インポート
- 2.6.2 パッケージ初期化
- 2.7 スコープ
- 2.3 変数
話題に上がった話
2.3.2 ポインタ
ここでは、Cの経験者から関数のローカル変数の参照が返せるという点がかなり驚く点だということが話題になりました。これは、後述の変数の生存期間におけるunreachableが関係していました。
2.3.3 new関数
ここでは、基本newは呼び出し毎に一意なアドレスを返すのですが、struct{}と[0]intが同じアドレスを指すことがあるようです。実装依存らしいのでどの実装でそれが起きるのかは気になります。
2.3.4 変数の生存期間
ここでは、Goではインスタンスの生成は宣言文が実行される毎に行われること、変数は「到達不能(unreachable)」になるまで生存し続けること。が話題になりました。到達不能が分かりづらいらしくちょっと話をしたんですが、要するに変数へ到達することのできる参照などの経路がプログラム中にあるかないか等は無しだと思います。真面目に追うとGCをちゃんとやらないといけなくなるのでそれは別途追いたいと思います。参考になりそうなURL。
2.5 型宣言
ここでは、同じ基底型を持つ名前付き型(namede type)同士が比較したりが出来ないと言うことが話題になりました。これは、比較してはいけない物とか計算してはいけない物などをうっかり同じ型で宣言してしてしまうミスを防ぐコトができるという意味で役立つので便利ですね。なおかつ、Goの場合はコンパイルエラーで検出可能な点が素晴らしいです。
2.6 パッケージとファイル
importしたときに別の名前が付けられる点と、詳細なコメントは、doc.goと呼ばれるファイルに書かれるという慣習が有ることを知りました。
Godoc: documenting Go codeここに色々書かれていて例としてSource file src/encoding/gob/doc.goが乗っていました。
2.6.2 パッケージ初期化
パッケージ変数の初期化が、書かれた順番で上からでは無く、依存関係が解決されてその順番で行われることが話題になりました。これは、依存関係を意識して順番に書く必要が無いということなので別の目的で順番を決めたり出来るので良さそうですね。
2.7 スコープ
ここでは、内側の宣言により外側の宣言へのアクセスが出来なくなるシャドーイング(shadow)が話題になりました。現場で実際に何人か関数を外部で宣言して、main内部で同じ名前の変数を宣言したところこのshadowでアクセスが出来なくなることが確認できました。
あとは、パッケージ変数をinit関数で初期化するときに省略変数宣言を使用するとうっかりローカル変数を宣言してしまうことになり、謎の挙動にナルト言うことも話題になりました。
個人的には、途中で出てきた、Fatalfという関数の中身が気になって調べてみたらstd.Outputという処理が出てきましてこの引数に2というものが出てきて、これはファイルディスクリプタの標準エラーを指している物なのだと思いますが、いろんな処理系で動くGoで直に書かれていることはびっくりしました。
func Fatalf(format string, v ...interface{}) {
std.Output(2, fmt.Sprintf(format, v...))
os.Exit(1)
}
ここまで呼んだところで、時間になりました。次回は 3 基本データ型 からです。