-2

I have trouble finding answer to the following question.

I have an interface and a struct that implements it.

type InterfaceA interface {
   DoA()
}

type ImplementsA struct {}

func (a ImplementsA) DoA() {
   fmt.Println("do A")
}

The question is: why can't I use a slice of ImplementsA to pass it to a function, that expects a variadic number of InterfaceA arguments?

func UsesVariadicNumberOfA(as ...InterfaceA) {
    for _, a := range as {
        a.DoA()
    }
}

func main() {
    a1 := ImplementsA{}
    a2 := ImplementsA{}
    as := []ImplementsA{a1, a2}
    
    // this does not compile, with "cannot use as (variable of type []ImplementsA) as []InterfaceA [...]"
    UsesVariadicNumberOfA(as...)

    // this works, of course
    ais := []InterfaceA{a1, a2}
    UsesVariadicNumberOfA(ais...)
}
  • "why can't I use a slice of ImplementsA to pass it to a function, that expects a variadic number of InterfaceA arguments?" Because Go's type system has neither co- no contravaraiance. See also https://golang.org/doc/faq#convert_slice_of_interface. 100% duplicate. – Volker Aug 02 '21 at 15:35

1 Answers1

0

The error message of compiler just say the answer.

Notice that the parameter type of this function is InterfaceA

func UsesVariadicNumberOfA(as ...InterfaceA) {
    for _, a := range as {
        a.DoA()
    }
}

But use put the type of ImplementsA in it

// type of as is []ImplementsA !!
UsesVariadicNumberOfA(as...)

just write another function and its parameter type is ImplementsA will solve this problem.

BWbwchen
  • 1
  • 1
  • See also https://golang.org/doc/faq#convert_slice_of_interface. – bcmills Aug 02 '21 at 15:12
  • BWbwchen, that is not a typo. InterfaceA is an interface which is implemented by ImplementsA, so if it would be just a simple single argument and not variadic it would work fine. If I have a function with signature: func UsesSingleA(a InterfaceA) {...} ...and would use it with the _a1_ variable used in the main like this: UsesSingleA(a1) it would work perfectly. The answer to my question is what @bcmills linked. Thanks for that, @bcmills! – Máté Pusztai Aug 02 '21 at 15:25
  • Thanks for pointing out my fault, @bcmills and Máté-Pusztai ! – BWbwchen Aug 03 '21 at 01:16