I have a type XY that has various fields and methods (a few dozen).
type XY struct {
Name string
SomeValue int
...
}
func (xy *XY) Do1() { ... }
func (xy *XY) Do2() { ... }
func (xy *XY) Do3() { ... }
...
Now I want to define a second type that embeds XY, keeping all fields and methods. But I do want to modify a few functions.
type AB struct {
XY
}
func (ab *AB) Do2() { ... }
So far so good. Now I want to pass AB to a function that takes XY.
func SomeFunc(xy *XY) { ... }
And here's where I stumble, no polymorphism.
I can pass *AB.XY
to the function, but that wouldn't make use of AB's Do2 function anymore. I could make an interface for it, which is probably the intended way, but if SomeFunc were to need near to all functions of XY, say getters of almost all fields, I'd basically need to create a copy of XY, as an interface (possible use case: I'm on a server and have to send values to a client in a specific way). I wouldn't want to only make it an interface, because I'd have to redefine all fields and functions in all types that are using the interface.
I can think of solutions for this problem, e.g. making Do2 a closure, that is set depending on the "host" type, or an enum field in XY and changing the behavior of Do2 based on that "type" variable, or using reflection and interface{}
in SomeFunc, but I'd like to know what the "correct" way in Go would be. How do you do this in the most efficient way, even if you have a lot of functions?
The correct way to do it in Go is to use interfaces. Create an interface of Do1
, Do2
, etc. and make SomeFunc work with the interface type.