W.I.S. Laboratory
menu-bar

Go言語


Goでコンストラクタ

Goは仕様上コンストラクタを持っていない。
というかそもそもオブジェクト指向型言語ではない。
C言語からC++とは別の方向へ進化した側面があり、かなりシンプルな言語だ。
ただ構造体と関数を紐付けることができるので、今風に「インスタンス生成をして関数を呼び出す」ような書き方をすることができる。
そのGoで無理やりコンストラクタ的なことをするには、適当な関数を作り、その中で構造体を作成して必要な処理した後に、構造体へのポインタを返せばそれっぽい動きになる。
関数名は何でも良いのだが、従来のオブジェクト指向型言語に倣って「New」+「構造体名」という名前を付けるのが慣例化しているようだ。

上の例では NewFoo() 関数内で生成した構造体のアドレスを返している。
CやC++やRustでこんなことをしたら、コンパイラに「スコープアウトしてしまうローカル変数のアドレスを返してるよ!」と注意されるのだが、Goなら大丈夫だ。
Goはその領域がスタックかヒープかをプログラマーが気にする必要はなく、その変数が参照され続ける限りメモリ上に生き続ける仕様になっているのでこんなことができる。
その変数が外部関数から参照されているか否かで、Goのコンパイラがスタック上に確保するかヒープ上に確保するかを自動判別してうまくやりくりしてくれるようになっているわけだ。
ヒープ上に確保された後にどこからも参照されなくなってしまった変数は、やがてガーベージコレクタが拾ってくれる。
Goは随分コンパイラが気を利かせてくれる言語だ。
上の例だと main() 内で受け取った f は構造体本体ではなくポインタ(アドレス)なので、CやC++ならアロー演算子を使って「f->val1」とするかデリファレンスして「(*f).val1」としてアクセスしないといけないのだが、Goはそんなことをまったく考えなくてもいい。


[ 戻る ]
saluteweb