I'm trying to create a cloneable interface and am running into some problems getting structs to implement the interface. It appears this is a limit of go which isn't in many other langauges. I'm trying to understand the justification for this limit.
var _ Cloneable = test{}
type Cloneable interface {
Clone() Cloneable
}
type test struct {
}
func (t *test) Clone() *test {
c := *t
return &c
}
Playground: https://play.golang.org/p/Kugatx3Zpw
Followup question since it still seems weird to me. This also does not compile
var _ Cloneable = &test{}
type Cloneable interface {
Clone() Cloneable
}
type Cloneable2 interface {
Clone() Cloneable2
}
type test struct {
}
func (t *test) Clone() Cloneable2 {
c := *t
return &c
}
Playground: https://play.golang.org/p/jlyMDPF1WB
I found this thread which talks about it and the answer seems to be supporting covariant function types would make the language harder to understand for little benefit. https://github.com/golang/go/issues/7512
At least they made a conscious decision to not support a feature supported by most other languages. I don't really buy it, but oh well...
To satisfy an interface method, the argument and return types must use the same types used in the interface declaration. The Clone
method must return a Cloneable
to satisfy the interface:
func (t *test) Clone() Cloneable {
c := *t
return &c
}
The Clone
method cannot return a *test
or Cloneable2
because these types are not the Cloneabl
e type.
The pointer type implements the interface:
var _ Cloneable = &test{}
Because the test
type must satisfy the Cloneable
interface for the Clone
method to compile, this compile time assertion is not needed.
(The question is a moving target. This is an answer to two previous edits of the question.)