The former declares a nil slice value, while the latter is non-nil but zero-length. They are functionally equivalent—their len and cap are both zero—but the nil slice is the preferred style.
Note that there are limited circumstances where a non-nil but zero-length slice is preferred, such as when encoding JSON objects (a nil slice encodes to null , while []string{} encodes to the JSON array [] ).
The latter of these is useful for when appending to a slice.
three
This makes a nil slice which isn’t quite the same thing as an empty slice. A nil slice is perfectly well behaved, has len(lines) == 0 and cap(lines) == 0. I would use this form if I was planning to append some (or no) items to it.
Interestingly when I compiled a simple function with each init method in, one and three produced identical code - basically zeroing the slice structure. two produced a lot more code, actually allocating stuff on the heap.