Go中[] Foo(nil)和[] Foo {}之间的区别

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).)

What I've tried

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.