Slices in Go may be represented by 3 parts:
ptr
– a pointer to the underlying array that accommodates information of the slicelen
– size, variety of parts within the slicecap
– capability, variety of parts within the underlying information array, ranging from the factor pointed by theptr
A nil
slice declared as var s1 []string
has no underlying information array – it factors to nothing. An empty slice, declared as s2 := []string{}
or s3 := make([]string, 0)
factors to an empty, non-nil array.
See additionally intimately what’s the distinction between size and capability of slices
See the desk to match the properties of the nil
and empty slices.
ptr | len | cap | |
---|---|---|---|
nil: []string |
0 | 0 | 0 |
empty: []string{} |
<addr> | 0 | 0 |
empty: make([]string, 0) |
<addr> | 0 | 0 |
The <addr>
is a non-zero deal with to an empty, non-nil array.
package deal predominant
import "fmt"
func predominant() {
var s1 []string // nil
s2 := []string{} // empty
s3 := make([]string, 0) // empty, equal to s2 := []string{}
fmt.Printf("s1 is nil: %t, len: %d, cap: %dn", s1 == nil, len(s1), cap(s1))
fmt.Printf("s2 is nil: %t, len: %d, cap: %dn", s2 == nil, len(s2), cap(s2))
fmt.Printf("s3 is nil: %t, len: %d, cap: %dn", s3 == nil, len(s3), cap(s3))
}
Output:
s1 is nil: true, len: 0, cap: 0
s2 is nil: false, len: 0, cap: 0
s3 is nil: false, len: 0, cap: 0
Empty and nil
slices behave in the identical approach that’s the built-in capabilities like len()
, cap()
, append()
, and for .. vary
loop return the identical outcomes. So, because the nil
slice declaration is easier, you must desire it to creating an empty slice. Nonetheless, there are some circumstances when you might want the empty, non-nil slice. For example, once you wish to return an empty JSON array []
as an HTTP response, you must create the empty slice ([]string{}
or make([]string, 0)
) as a result of for those who use a nil
slice, you’ll get a null
JSON array after encoding:
package deal predominant
import (
"encoding/json"
"fmt"
"log"
)
func predominant() {
var s1 []string // nil
s2 := []string{} // empty
s3 := make([]string, 0) // empty, equal to s2 := []string{}
s1JSON, err := json.Marshal(s1)
if err != nil {
log.Deadly(err)
}
fmt.Printf("s1 JSON: %sn", string(s1JSON))
s2JSON, err := json.Marshal(s2)
if err != nil {
log.Deadly(err)
}
fmt.Printf("s2 JSON: %sn", string(s2JSON))
s3JSON, err := json.Marshal(s3)
if err != nil {
log.Deadly(err)
}
fmt.Printf("s3 JSON: %sn", string(s3JSON))
}
Output:
s1 JSON: null
s2 JSON: []
s3 JSON: []