-1

I have an interface

type FooInterface interface {
    HasName() bool
}

It has a base implementation that I intend to use in other implementation of FooInterface

type FooBoilerplate struct {
    hasName bool
}

func (f *FooBoilerplate) HasName() bool {
    return f.hasName
}

Like so

type Foo1 struct {
    fooId int
    FooBoilerplate
}

func (f *Foo1) GetId() int {
    return f.fooId
}

I want to create a container class for FooInterface using generics

type FooContainer[T FooInterface] struct {
    list []T
}

func (fc *FooContainer[T]) AddItem() {
    var t T

    fc.list = append(fc.list, t)

}

However I get compilation errors when I try to instantiate the container

func RunThis() {
    foo1 := Foo1{FooBoilerplate: FooBoilerplate{hasName: false}}

    // works fine
    TakesFooInterface(&foo1)

    // doesnt compile
    fc := FooContainer[Foo1]{}
    fc.AddItem()
}

Not sure why Foo1 is seen to implement FooInterface when passed to a function, but isnt when passed tot he container struct. I cant pass an object to the container instantiation either.

blackgreen
  • 34,072
  • 23
  • 111
  • 129
  • marginally related: [How to implement generic interfaces?](https://stackoverflow.com/questions/72034479/how-to-implement-generic-interfaces) – blackgreen Jul 04 '22 at 21:30

2 Answers2

2

Foo1 doesn't implement FooInterface. *Foo1 does. This is true irrespective of whether the interface is used as the type of a function argument or as a constraint.

That is why you pass &foo1 (type *Foo1) to TakesFooInterface and not foo1 (type Foo1).

Likewise for the type parameter, you should instantiate the generic type with *Foo1:

fc := FooContainer[*Foo1]{}
blackgreen
  • 34,072
  • 23
  • 111
  • 129
Hymns For Disco
  • 7,530
  • 2
  • 17
  • 33
0

I assume your TakesFooInterface is like this:

func TakesFooInterface(foo1 FooInterface) {
   ...
}

Then the call TakesFooInterface(foo1) failed to compile, as foo1 does not implement FooInterface but &foo1.

The same with your generic case, the Foo1 type does not implement FooInterface which requires the pointer access in the method HasName but *Foo1 type does.

I have copied your code with some of my tryings on Go.Dev: https://go.dev/play/p/3I2mtabi-ub

khiemfle
  • 9
  • 1