Go読書会 #9 がランサーズ株式会社で行われたので進捗と技術的なメモ書きを書いておきます。読書会の内容はプログラミング言語Goを冒頭から皆で読み進めていくというものです。
進捗した内容
- 5章 関数
- 5.8 遅延関数呼び出し
- 5.9 パニック
- 5.10 リカバー
- 6章 メソッド
- 6.1 メソッド宣言
- 6.2 ポインタレシーバを持つメソッド
- 6.2.1 nilは正当なレシーバー値
話題に上がった話
5.8 遅延関数呼び出し
ここでは、予約語deferの話がメインになっています。defer構文を使うと、defer文を含む関数が完了するまでその実行が遅延される
ので、資源解放等の処理を確実に行うことが出来ます。また、この手の処理は資源獲得と対応付けて置かないと分かりづらくなるので、そう言う意味でもよく考えられている機能だと思います。
func run() {
defer fd.Close() // run終了後に実行される
}
面白いと思ったところは、無名関数を使用して関数が呼び出し元に返す値を変更することさえできる
というところです。webframeworkだと割とありがちなafter hookとかが簡単に実現出来ます。
5.9 パニック
ここでは、Goのランタイムが誤りを検出したときに起きるpanicについての話でした。panic自体は他の言語の例外に似ているのですが、使用される状況が異なっていて重大なエラーに対して使われる
ようです。
他に興味深かったのは、panicが起きたときのGoランタイムの挙動で、Goのパニック機構はスタックが巻き戻される前に遅延された関数を実行する
というところでした。先程出てきたdefer文が実行されてから巻き戻されるんですね。(C++だとこんな感じのようです。javaはこんな感じのようです。)
5.10 リカバー
ここでは、recover関数についての説明がありました。先程出てきたpanicが起きた場合にdeferで遅延関数内部にrecoverがあった場合、パニックの現状を終了させてパニック値を返します
。こうすることで、panic状態から回復して関数が正常にリターンするところから復帰することができます。興味深かったのは、公開APIは失敗をエラーとして報告すべき
であるといところで、所謂他の言語の例外のようにpanicを扱うべきでは無いというところです。こういう哲学がきっちり明示されていると開発する側もやりやすいです。
6.1 メソッド宣言
ここでは、特定の型に関連づけられた関数
であるメソッドについて書かれていました。所謂OOPの様なことをGoで行うための機能です。関数定義にレシーバ
というパラメータを追加して定義します。パッケージレベル関数宣言とメソッドの宣言は名前がぶつかっても違う存在のため問題は無い用です。
6.2 ポインタレシーバを持つメソッド
ここでは、型に紐付けられた値を更新したい場合にレシーバーはポインタ型である必要があることが主な内容なのですが、気になったところは、慣習上、厳密に必要なくてもすべてのレシーバーはポインタレシーバーにすべき
というところです。このへんのGoの割り切り具合が私は結構好きです。
ここまで読んだところで時間になりました。次回は 6.3 構造体埋め込みによる方の合成 からです。