I'm new to Go and would like to know the difference between []Foo(nil)
and []Foo{}
.
(I'm using this in my tests, where I want to specify that when my function errors, it should return nil, err
. The go linter complains when I use nil
or []Foo{}
, but works when I use []Foo(nil)
.)
I had a look at the Go docs and on SO and found Struct stuff about Foo{}
but not []Foo(nil)
.
When I use []Foo{}
, the test failure outputs:
expected: []Foo{}
actual : []Foo(nil)
Fmt outputs for []Foo(nil)
and []Foo{}
are the same:
fmt.Println([]Foo(nil)) // []
fmt.Println([]Foo(){}) // []
fmt.Printf([]Foo(nil)) // []Foo
fmt.Printf([]Foo(){}) // []Foo
I noticed that if I write just Foo(nil)
(without the []
) then the linter complains about cannot convert nil to type Foo
.
So my only guess is that []Foo(nil)
invokes some type coercion. Can anyone help me out?
The expression []Foo(nil)
is a conversion. It converts the untyped nil to a nil slice of type []Foo
.
The expression []Foo{}
is a composite literal that returns a empty slice. It's empty because no elements are listed between the {}
.
This might help explain the difference:
fmt.Println([]Foo(nil) == nil) // prints true
fmt.Println([]Foo{} == nil) // prints false
A nil slice does not have a backing array. An empty slice has a backing array with length 0.
What's confusing is that the fmt package can output the same data for empty slices and nil slices.
If the distinction between a nil slice and empty slice is not important in your tests, then test with len(s) == 0
. This expression evaluates to true for both nil slices and empty slices.