https://blog.p1ass.com/posts/go-faq/

こんにちは、@p1assです。

最近研修で Go を書いていて、その際にいくつか質問をされるのですが、聞いてみると前にも答えたような質問が多かったので、これを機にブログに参考リンクをまとめようと思います。 質問された際にすぐ答えられない質問も数多くあり、調べたり教えてもらったりすることで様々なことを再発見できました。

この記事では、質問に対する回答をできるだけ公式に近い文章を引用する形で書き記します。私個人の考えは別の段落になるようにして、事実と意見を区別するように心がけています。

なにか誤りを見つけた際は GitHub で PR を投げていただけると助かります。

言語仕様

関数の引数は値渡しか参照渡しか?

Go はすべて値渡し (pass by value) です。 ポインタの場合は、ポインタそのものがコピーされポインタの指し示す先の値はコピーされません。

Go の多値返却はタプルか?

「タプル」の定義が言語仕様上定められていないので、Yes/No で答えられません。 ただし、仕様書には “tuple assignment” というものが存在し、

A tuple assignment assigns the individual elements of a multi-valued operation to a list of variables.

x, y = f()

ひとつの形態として多値返却する関数呼び出しを多変数で受ける例があげられています。

make([]int, 10, 100) の第三引数の意味は?

make の第三引数はキャパシティと呼ばれ、どれだけのメモリを確保するかを指定できます。予めスライスの長さ以上のメモリを確保することで、append 時のメモリ再確保の回数を減らすことができます。

map[string]struct{}struct{} は何?

struct{} は empty struct と呼ばれ、フィールドを持たない構造体です。empty struct のメリットはメモリのサイズが 0 であることです。つまり、どれだけ使ってもメモリを消費しません。

私見

例えば、値の重複を取り除く実装を map の key を使って実装した場合、value に入れる型は何でも良いです。こういった場合に empty struct を使うことで bool を指定するよりもメモリ使用量を抑えられます。