はじめに
本記事は以下のツイートの翻訳転載です。
空スライスとnilスライス
値を持たないスライスを使用するには2つの方法があります。
var
の使用:var t []int
この方法はint
型のスライスt
を初期化せずに宣言します。
このスライスはnilとみなされます。
これは、実際には基底となる配列が存在しないことを意味します。
スライスの長さ (len
) と容量 (cap
) はどちらも0
です。
- リテラルの使用: t := []int{}
var
の使用とは異なり、このスライスはnil
ではありません。
これは要素を持たない配列を基底するスライスです。
さて、慣例とみなされるのはどちらでしょうか。
1 . nilスライスはメモリを割り当てません
空スライスが基底となる配列に少量のメモリを割り当てるのに対して、
nilスライスは対象の存在しないただのポインタです。
ほとんどの場合、この差は無視できるものですが、
高いパフォーマンスを求められるアプリケーションでは大きな差になる可能性があります。
2 . シンプルさとゼロ値というGo言語の哲学により慣用的であると考えられているため、Goのコミュニティはnilスライスのアプローチを好んでいます
3 . 例外もあります
たとえば、JSONを扱う場合、nilスライスと空スライスでは動作が異なります。
A nil slice (var t []int) encodes to JSON as null, whereas an empty slice (t := []int{}) encodes to an empty JSON array ([]).
nilスライス(var t []int
)はJSONにnull
としてエンコードされますが、
空スライス(t := []int{}
)は空のJSON配列([]
)にエンコードされます。
4 . また、要素を持つスライス、空スライス、およびnilスライスを同様に扱うようにコードを設計することも慣用的です。
Goに十分慣れているならご存知かと思いますが、
for range
、len
、append
などでnilスライスを使用してもパニックにならずに動作します。
おわりに
スライスとその基底配列の関係については以下わかりやすかった。