I was reading the source code of the Middleware's chaining software Alice and found the expression:
func New(constructors ...Constructor) Chain {
return Chain{append(([]Constructor)(nil), constructors...)}
}
I have no problem with the code at all, except that i have never seen the expression ([]Slice)(nil)
before. Does anybody have any information about this sort of expression?
It copies the constructors
argument into a new slice, assigned it to a field in the Chain
literal, and returns the new struct.
It is equivalent to
func New(constructors ...Constructor) Chain {
var tmp []Constructor
tmp = append(tmp, constructors...)
return Chain{tmp}
}
The author of alice here, just randomly clicked on this question. :)
The other answers explain what the append(nil, ...)
does - I use it throughout the library to copy the slices that the user passes in.
Now, Go does not allow to simply use append(nil, someElement)
because the type of nil
is unknown. ([]Constructor)(nil)
is casting nil
to the type []Constructor
in order to avoid this. This is a type conversion, same as, say, int64(123)
or (*int)(nil)
.
This is a minimal example where the compiler errors out because of an untyped nil:
a := ([]int)(nil)
a = append(a, 1, 2, 3) // works fine, a is of type []int
var b []int
b = append(b, 1, 2, 3) // works fine, b is of type []int
c := nil
c = append(c, 1, 2, 3) // compiler error: the type of c is unknown