Slice interfaces inference is not possible?

Hello
I’ve got two interfaces which have some identical methods Wait()

type A interface {
	Wait() time.Duration
}

type B interface {
	Wait() time.Duration
	Use() time.Duration
}

I’ve got a struct foo wich implement both interfaces

type foo struct {
	wait time.Duration
	use time.Duration
}

func (f* foo) Wait() time.Duration { return f.wait } 
func (f* foo) Use() time.Duration { return f.use } 

I would like to know why compiler refuse to compile
a function with a ...A defined parameters when I use []B... as argument


func WorkWithTypeA(lst ...A) {}

func main()  {
	listOfElementAsB := []B{&foo{wait:time.Duration(1*time.Second)},&foo{wait:time.Duration(1*time.Second)}}
	WorkWithTypeA(listOfElementAsB... ) // <- not compile: cannot use listOfElementAsB (type []B) as type []A in argument to WorkWithTypeA
}

Because if I use only one parameter that work

func main() {
	oneElementAsB:= B(&foo{wait:time.Duration(1*time.Second)})
	WorkWithTypeA(oneElementAsB) // no complaine
}

full example in playground

Someone could explain me what happen ?

https://golang.org/doc/faq#convert_slice_of_interface

Because A and B are separate types. []A and []B are also separate types. A very big problem with allowing this is the following problem:

func WorksWithAll(all ...interface{}) {
    // ...
}

func main() {
    ints := []int{1, 2, 3, 4}
    WorksWithAll(ints...) // does not compile
}

The big issue with doing this is that []int and []interface{} have separate memory layouts, so you would need to copy the slice, which is better to do explicitly.

An even bigger issue if we allowed this:

func EditFirstElement(i ...interface{}) {
    i[0] = "hello world"
}

func main() {
    allTypes := []interface{}{5, 3+8i, "some more stuff"}
    ints := []int{1, 2, 3, 4, 5}

    EditFirstElement(allTypes...) // Actually changes the first element of allTypes to "hello world"
    EditFirstElement(ints...) // uh oh...
}

playground: https://play.golang.org/p/-Ezolon-u0R

2 Likes

Thanks but it’s not what I expected :slight_smile:

I would like to know why compiler refuse to compile
a function with a ...A defined parameters when I use []B... as argument

Why []B... is not spliting my slice to elements like B, B, B ? because that’s what I expected

func WorkWithTypeA(lst ...A) {}

func main()  {
	listOfElementAsB := []B{&foo{wait:time.Duration(1*time.Second)},&foo{wait:time.Duration(1*time.Second)}}
	WorkWithTypeA(listOfElementAsB[0], listOfElementAsB[1] ) // no complain
}

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.