Can someone please explain as to why duck typing does not work when a slice is passed to the variadic function.
Cases 1 and 2 as indicated below seems to work, but case-3 below initializes a slice and thereafter passes the dereferenced slice to the function that accepts the interface.
The error message is : cannot use gophers (type []Gopher) as type []Animal in argument to runForest
package main
import (
"fmt"
)
type Animal interface {
Run() string
}
type Gopher struct {
}
func (g Gopher) Run() string {
return "Waddle.. Waddle"
}
func runForest(animals ...Animal) {
for _, animal := range animals {
fmt.Println(animal.Run())
}
}
func main() {
//works
runForest(Gopher{})
//works
runForest(Gopher{},Gopher{})
// does not work
gophers := []Gopher{{},{}}
runForest(gophers...)
}
As Volker mentions in the comments, slices can't be implicitly converted the way their elements can. A Gopher
can quack like an Animal
, but a []Gopher
can't quack like an []Animal
.
The minimal change to get this working is:
func main() {
gophers := []Gopher{{}, {}}
out := make([]Animal, len(gophers))
for i, val := range gophers {
out[i] = Animal(val)
}
runForest(out...)
}