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.
CodePudding user response:
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]{}
CodePudding user response:
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