I have a need to create multiple structs with almost the same fields and methods with the same actions. Instead of doing that I thought, why not create a single struct and use interfaces to limit interactions. It worked great! Now the problem. I want the methods to be chainable. To do that, methods need to return a reference to the struct. After doing that, all the returns complain that (struct) does not implement <interface> (wrong type for <method> method)
. Which is expected.
The question is, is it possible to use a single struct with multiple interfaces that has chainable methods? Or is creating individual, duplicate, structs for every interface the only way?
I thought of using composition but I still need to define methods that will call the embedded struct methods, in which case there's no difference to creating new pure structs.
Example problem:
https://play.golang.org/p/JrsHATdi2dr
package main
import (
"fmt"
)
type A interface {
SetA(string) A
Done()
}
type B interface {
SetB(string) B
Done()
}
type t struct {
a string
b string
}
func (t *t) SetA(a string) *t { t.a = a; return t }
func (t *t) SetB(b string) *t { t.b = b; return t }
func (t *t) Done() { fmt.Println(t.a, t.b) }
func NewTA() A {
return &t{}
}
func NewTB() B {
return &t{}
}
func main() {
fmt.Println("Hello, playground")
ta := NewTA()
ta.SetA("a")
ta.Done()
tb := NewTB()
tb.SetB("b")
tb.Done()
}
When you use *t
as return type in SetA
and SetB
that means t
are not implement A and B interface. The signature of SetA
and SetB
function of *t
doesn't match with interface A and B accordingly.
Accually SetA(a string) A
and SetA(a string) *t
are not same think. You used A
as return type for SetA
in interface but use *t
as return type for t
, go doesn't support this. Same for SetB
function
If you do like this then it will work because now function signature matched
func (t *t) SetA(a string) A { t.a = a; return A(t) }
func (t *t) SetB(b string) B { t.b = b; return B(t) }
Code in go playground here