ynk800のメモ帳

イベントの参加記録や備忘録などを書いていきます。

A Tour of Goのメモ2

前書き

前回の続き。 y-nk800.hatenablog.com

defer

defer ステートメントは、 defer へ渡した関数の実行を、呼び出し元の関数の終わり(returnする)まで遅延させるものです。 defer へ渡した関数の引数は、すぐに評価されますが、その関数自体は呼び出し元の関数がreturnするまで実行されません。

deferは関数のreturnのタイミングで別の関数を呼び出す仕組みらしい。 deferは1関数内で複数回呼び出すことができ、呼び出す関数はスタックに積まれる。 スタックに積まれた関数はLIFO(Last In First Out)の順に実行される。

例えば、下記のようなコード

これを実行すると、

This
is
defer
sample.

と出力される。

Closeが必要なリソースの処理などの後始末に有用。Javaのfinallyっぽい使い方ができる。

興味深いのが、こちらのコード。

実行すると、2が表示される。 多分、下記の順番で処理が行われる

  1. defer func() {i++}()の宣言により、関数がスタックに積まれる。この段階ではまだ式は評価されない。
  2. return 1の処理で、名前付き戻り値の変数iに1が代入される
  3. returnが呼び出されたのでスタックに積まれた関数が評価され、iがインクリメントされる
  4. 処理が呼び出し元に(インクリメント後の値で)返る

名前付き戻り値に慣れていないと不思議な挙動に見えて面白い。