質問: Goに限らないトピックかもしれません。 次のような、データベースからデータを読み込む関数(インライン展開されない)を利用する関数があったとします。返されたオブジェクトの生存期間はこの関数内のみとします。 ``` func doSomething() { // getUser()はDBから読み込んで結果を返す関数 user, err := getUser() } ``` この時、`getUser()`の実装パターンとして、値返しのパターンとポインタ返しの2パターンが考えられます。 * ポインタ返しの場合 構造体のコピーは発生しませんが、`doSomething()`を大量に呼ぶとGC対象オブジェクトがヒープにたまる。 * 値返しの場合 ヒープにオブジェクトは作成しないが、構造体のコピーが発生するのでポインタ返しより実行がやや遅い? Goの場合、この使い分けはどこで判断するのがよいでしょうか?
回答: コピーコストが問題になる場合を除いては、基本的に値を返すべきです。 なるべく値型を使用したほうがいい理由の一つとして、コードの保守性の問題があります。 値型の場合、メンバへのアクセスがエラーを引き起こさないことはコンパイル時に確定しています。 しかし、ポインタの場合は参照先が存在するかどうかは実行時にしか分かりません。 つまり、アクセスする前に`nil`でないかどうかをチェックするか、関数がエラーを返していない場合に`nil`を返さないことを知っている上で取り扱わないと、`panic`を引き起こす可能性があります。