Ensuring embedded structs implement interface without introducing ambiguity - oop

I'm trying to clean up my code base by doing a better job defining interfaces and using embedded structs to reuse functionality. In my case I have many entity types that can be linked to various objects. I want to define interfaces that capture the requirements and structs that implement the interfaces which can then be embedded into the entities.
// All entities implement this interface
type Entity interface {
Identifier()
Type()
}
// Interface for entities that can link Foos
type FooLinker interface {
LinkFoo()
}
type FooLinkerEntity struct {
Foo []*Foo
}
func (f *FooLinkerEntity) LinkFoo() {
// Issue: Need to access Identifier() and Type() here
// but FooLinkerEntity doesn't implement Entity
}
// Interface for entities that can link Bars
type BarLinker interface {
LinkBar()
}
type BarLinkerEntity struct {
Bar []*Bar
}
func (b *BarLinkerEntity) LinkBar() {
// Issues: Need to access Identifier() and Type() here
// but BarLinkerEntity doesn't implement Entity
}
So my first thought was to have FooLinkerEntity and BarLinkerEntity just implement the Entity interface.
// Implementation of Entity interface
type EntityModel struct {
Id string
Object string
}
func (e *EntityModel) Identifier() { return e.Id }
func (e *EntityModel) Type() { return e.Type }
type FooLinkerEntity struct {
EntityModel
Foo []*Foo
}
type BarLinkerEntity struct {
EntityModel
Bar []*Bar
}
However, this ends up with an ambiguity error for any types that can link both Foos and Bars.
// Baz.Identifier() is ambiguous between EntityModel, FooLinkerEntity,
// and BarLinkerEntity.
type Baz struct {
EntityModel
FooLinkerEntity
BarLinkerEntity
}
What's the correct Go way to structure this type of code? Do I just do a type assertion in LinkFoo() and LinkBar() to get to Identifier() and Type()? Is there any way to get this check at compile time instead of runtime?

Go is not (quite) an object oriented language: it does not have classes and it does not have type inheritance; but it supports a similar construct called embedding both on struct level and on interface level, and it does have methods.
So you should stop thinking in OOP and start thinking in composition. Since you said in your comments that FooLinkerEntity will never be used on its own, that helps us achieve what you want in a clean way.
I will use new names and less functionality to concentrate on the problem and solution, which results in shorter code and which is also easier to understand.
The full code can be viewed and tested on the Go Playground.
Entity
The simple Entity and its implementation will look like this:
type Entity interface {
Id() int
}
type EntityImpl struct{ id int }
func (e *EntityImpl) Id() int { return e.id }
Foo and Bar
In your example FooLinkerEntity and BarLinkerEntity are just decorators, so they don't need to embed (extend in OOP) Entity, and their implementations don't need to embed EntityImpl. However, since we want to use the Entity.Id() method, we need an Entity value, which may or may not be EntityImpl, but let's not restrict their implementation. Also we may choose to embed it or make it a "regular" struct field, it doesn't matter (both works):
type Foo interface {
SayFoo()
}
type FooImpl struct {
Entity
}
func (f *FooImpl) SayFoo() { fmt.Println("Foo", f.Id()) }
type Bar interface {
SayBar()
}
type BarImpl struct {
Entity
}
func (b *BarImpl) SayBar() { fmt.Println("Bar", b.Id()) }
Using Foo and Bar:
f := FooImpl{&EntityImpl{1}}
f.SayFoo()
b := BarImpl{&EntityImpl{2}}
b.SayBar()
Output:
Foo 1
Bar 2
FooBarEntity
Now let's see a "real" entity which is an Entity (implements Entity) and has both the features provided by Foo and Bar:
type FooBarEntity interface {
Entity
Foo
Bar
SayFooBar()
}
type FooBarEntityImpl struct {
*EntityImpl
FooImpl
BarImpl
}
func (x *FooBarEntityImpl) SayFooBar() {
fmt.Println("FooBar", x.Id(), x.FooImpl.Id(), x.BarImpl.Id())
}
Using FooBarEntity:
e := &EntityImpl{3}
x := FooBarEntityImpl{e, FooImpl{e}, BarImpl{e}}
x.SayFoo()
x.SayBar()
x.SayFooBar()
Output:
Foo 3
Bar 3
FooBar 3 3 3
FooBarEntity round #2
If the FooBarEntityImpl does not need to know (does not use) the internals of the Entity, Foo and Bar implementations (EntityImpl, FooImpl and BarImpl in our cases), we may choose to embed only the interfaces and not the implementations (but in this case we can't call x.FooImpl.Id() because Foo does not implement Entity - that is an implementation detail which was our initial statement that we don't need / use it):
type FooBarEntityImpl struct {
Entity
Foo
Bar
}
func (x *FooBarEntityImpl) SayFooBar() { fmt.Println("FooBar", x.Id()) }
Its usage is the same:
e := &EntityImpl{3}
x := FooBarEntityImpl{e, &FooImpl{e}, &BarImpl{e}}
x.SayFoo()
x.SayBar()
x.SayFooBar()
Its output:
Foo 3
Bar 3
FooBar 3
Try this variant on the Go Playground.
FooBarEntity creation
Note that when creating FooBarEntityImpl, a value of Entity is to be used in multiple composite literals. Since we created only one Entity (EntityImpl) and we used this in all places, there is only one id used in different implementation classes, only a "reference" is passed to each structs, not a duplicate / copy. This is also the intended / required usage.
Since FooBarEntityImpl creation is non-trivial and error-prone, it is recommended to create a constructor-like function:
func NewFooBarEntity(id int) FooBarEntity {
e := &EntityImpl{id}
return &FooBarEntityImpl{e, &FooImpl{e}, &BarImpl{e}}
}
Note that the factory function NewFooBarEntity() returns a value of interface type and not the implementation type (good practice to be followed).
It is also a good practice to make the implementation types un-exported, and only export the interfaces, so implementation names would be entityImpl, fooImpl, barImpl, fooBarEntityImpl.
Some related questions worth checking out
What is the idiomatic way in Go to create a complex hierarchy of structs?
is it possible to call overridden method from parent struct in golang?
Can embedded struct method have knowledge of parent/child?
Go embedded struct call child method instead parent method

Seems to me having three ID in one structure with methods relying on them is even semantically incorrect. To not be ambiguous you should write some more code to my mind. For example something like this
type Baz struct {
EntityModel
Foo []*Foo
Bar []*Bar
}
func (b Baz) LinkFoo() {
(&FooLinkerEntity{b.EntityModel, b.Foo}).LinkFoo()
}
func (b Baz) LinkBar() {
(&BarLinkerEntity{b.EntityModel, b.Bar}).LinkBar()
}

Related

Extend calculator with complex and rational module(using dynamic binding)

I already made calculator that can compute with integers and real numbers(i made it with go).
Then I want to make it possible to calculate complex and rational numbers by adding those modules.
(it can also calculate when types are mixed)
It can be easy if I check types of operands every time(runtime) and take care of each case, but I want to solve it with dynamic binding. Guys can you tell me the idea of how to solve this problem
I think by dynamic typing, you're probably referring to how in eg C++ and Java, dynamic binding is essentially having reference to a base class that can point to a derived class (because the derived class "is a" base class).
One might say that the base class defines the interface behind which derived classes morph. If the derived classes replace methods of the base class, a reference to the base class can still access those methods in the derived class.
Base class can define some methods to provide some "base" functionality to its derived classes. If those classes don't redefine the method, the base class's method can be called.
In go, both these concepts exist, but they're quite different.
Go has an explicit interface keyword that defines method signatures but no methods. Any value implicitly satisfies that interface if it has methods of the same name with the same signature.
type LivingBeing interface {
TakeInEnergy()
ExpelWaste()
}
The interface type becomes a valid type in the code. We can pass an interface to a function, and without knowing the type satisfying that interface, can call its methods:
func DoLife(being LivingBeing) {
being.TakeInEnergy()
being.ExpelWaste()
}
This is valid code, but not complete code. Unlike with base classes in other languages, interfaces cannot define functions, only their signatures. It is purely and only an interface definition. We have to define the types that satisfy the interface separately from the interface itself.
type Organism struct{}
func (o *Organism) TakeInEnergy() {}
func (o *Organism) ExpelWaste() {}
We now have a type organism that satisfies LivingBeing. It is something like a base class, but if we wanted to build on it, we can't use subclassing because Go doesn't implement it. But Go does provide something similar called embedding types.
In this example I'll define a new organism, Animal, that draws ExpelWaste() from LivingBeing, but defines its own TakeInEnergy():
type Animal struct {
Organism // the syntax for an embedded type: type but no field name
}
func (a *Animal) TakeInEnergy() {
fmt.Printf("I am an animal")
}
What isn't obvious from that code is that because Animal's Organism is not a named field, its fields and methods are accessible directly from Animal. It's almost as if Animal "is an" organism.
However it is *not * an organism. It is a different type, and it would be more accurate to think of object embedding as syntactic sugar to automatically promote Organism's fields and methods to Animal.
Since go is statically and explicitly typed, DoLife cannot take an Organism and then be passed an Animal: it doesn't have the same type:
/* This does not work. Animal embeds organism, but *is not* an organism */
func DoLife(being *Organism) {
being.TakeInEnergy()
being.ExpelWaste()
}
func main() {
var a = &Animal{Organism{}}
DoLife(&Animal{})
}
cannot use &Animal{} (type *Animal) as type *Organism in argument to DoLife
That's why interface exists - so that both Organism and Animal (and indeed, even Plant or ChemotrophBacteria) can be passed as a LivingBeing.
Putting it all together, here's the code I've been working from:
package main
import "fmt"
type LivingBeing interface {
TakeInEnergy()
ExpelWaste()
}
type Organism struct{}
func (o *Organism) TakeInEnergy() {
}
func (o *Organism) ExpelWaste() {}
type Animal struct {
Organism
}
func DoLife(being LivingBeing) {
being.TakeInEnergy()
being.ExpelWaste()
}
func (a *Animal) TakeInEnergy() {
fmt.Printf("I am an animal")
}
func main() {
var a = &Animal{Organism{}}
DoLife(a)
}
There are a few caveats:
Syntactically, If you want to declare an embedded literal you must explicitly provide its type. In my example Organism has no fields so there's nothing to declare, but I still left the explicit type in there to point you in the right direction.
DoLife can call the right TakeInEnergy on a LivingBeing, but Organism's methods cannot. They see only the embedded Organism.
func (o *Organism) ExpelWaste() {
o.getWaste() //this will always be Organism's getWaste, never Animal's
}
func (o *Organism)getWaste() {}
func (a *Animal)getWaste() {
fmt.Println("Animal waste")
}
Simlarly if you pass only the embedded part, then it's going to call its own TakeInEnergy(), not that of Animal; there's no Animal left!
func main() {
var a = &Animal{Organism{}}
DoLife(&a.Organism)
}
In summary,
Define explict interface and use that type wherever you want "polymorphic" behavior
Define base types and embed them in other types to share base functionality.
Don't expect the "base" type to ever "bind" to functions from the "derived" type.

Non-interface methods in interface implementation

I have an interface which defines a method. I have a struct which implements this interface. In it, I have implemented the methods from this interface and also have additional methods defined.
For example:
package main
import (
"fmt"
)
type Animal interface {
MakeNoise()
}
type Dog struct {
color string
}
/* Interface implementation */
func (d *Dog) MakeNoise() {
fmt.Println("Bark!")
}
/* End Interface implementation */
func (d *Dog) WagTail() {
fmt.Println(d.color + " dog: Wag wag")
}
func NewDog(color string) Animal {
return &Dog{color}
}
func main() {
dog := NewDog("Brown")
dog.MakeNoise()
dog.WagTail()
}
On Playground: https://play.golang.org/p/B1GgoNToNl_l
Here, WagTail() is not part of the Animal interface but belongs to the Dog struct. Running this code gives an error
dog.WagTail undefined (type Animal has no field or method WagTail).
Is there a way I could have a struct adhere to an interface and also define it's own methods?
This may help you.
d := dog.(*Dog)
d.WagTail()
On Playground: https://play.golang.org/p/KlNqpmvFTJi
The error described it all:
dog.WagTail undefined (type Animal has no field or method WagTail)
To implement an interface you should implement all methods defined inside it.
dog := NewDog("Brown")
dog.MakeNoise()
dog.WagTail()
Now NewDog returns Animal interface which contains MakeNoise method but not WagTail.
The only way to manage your requirement is either create a variable of struct type Dog and then you can call any method having Dog as receiver.
d := &Dog{"Brown"}
d.WagTail()
Or you can return the pointer to Dog struct from NewDog method just like you did in your code mentioned in the comment as:
func NewDog(color string) *Dog {
return &Dog{color}
}
But if the method is not defined in interface you cannot implement it using the struct as method receiver.
Golang provides a way in which:
You can ask the compiler to check that the type T implements the
interface I by attempting an assignment using the zero value for T or
pointer to T, as appropriate
type T struct{}
var _ I = T{} // Verify that T implements I.
var _ I = (*T)(nil) // Verify that *T implements I.
If T (or *T, accordingly) doesn't implement I, the mistake will be caught at compile time.
If you wish the users of an interface to explicitly declare that they
implement it, you can add a method with a descriptive name to the
interface's method set. For example:
type Fooer interface {
Foo()
ImplementsFooer()
}
A type must then implement the ImplementsFooer method to be a Fooer, clearly documenting the fact and announcing it in godoc's output.
type Bar struct{}
func (b Bar) ImplementsFooer() {}
func (b Bar) Foo() {}
Most code doesn't make use of such constraints, since they limit the
utility of the interface idea. Sometimes, though, they're necessary to
resolve ambiguities among similar interfaces.
You can definitely do it, one such method is using type assertion as shown in the other answer here. Otherwise the answer by #Himanshu here describes the situation very well.
I would like to add to the discussion to further describe how you
could have a struct adhere to an interface and also define it's own methods
The MakeDog method returns an Animal, and there are a number of reasons you may consider returning a Dog (or whichever concrete type) directly.
The reason I bring this up is because of something someone told me about creating methods when I first started programming in Go:
Accept an Interface and return a Concrete type (such as a Struct)
Interfaces can accept any concrete type. That's why they are used when you don't know the type of argument you are passing to the function.
I did a google search with the following terms and quite a few articles turned up
golang accept interface, return struct
For example: https://mycodesmells.com/post/accept-interfaces-return-struct-in-go and http://idiomaticgo.com/post/best-practice/accept-interfaces-return-structs/
I have put together a little bit of a demo extending on your concepts in your question to try and clearly describe interface methods as well as methods and attributes for specific types
Taken from this snippet on Playground
package main
import (
"fmt"
)
type Animal interface {
MakeNoise() string
}
// printNoise accepts any animal and prints it's noise
func printNoise(a Animal) {
fmt.Println(a.MakeNoise())
}
type pet struct {
nLegs int
color string
}
// describe is available to all types of Pet, but not for an animal
func (p pet) describe() string {
return fmt.Sprintf(`My colour is "%s", and I have "%d" legs`, p.color, p.nLegs)
}
type Dog struct {
pet
favouriteToy string
}
// MakeNoise implements the Animal interface for type Dog
func (Dog) MakeNoise() string {
return "Bark!"
}
// WagTail is something only a Dog can do
func (d Dog) WagTail() {
fmt.Println("I am a dog,", d.pet.describe(), ": Wags Tail")
}
type Cat struct {
pet
favouriteSleepingPlace string
}
// MakeNoise implements the Animal interface for type Cat
func (Cat) MakeNoise() string {
return "Meow!"
}
// ArchBack is something only a Cat can do
func (c Cat) ArchBack() {
fmt.Println("I am a cat,", c.pet.describe(), ": Arches Back")
}
type Bird struct {
pet
favoritePerch string
}
// MakeNoise implements the Animal interface for type Cat
func (Bird) MakeNoise() string {
return "Tweet!"
}
// Hop is something only a Bird can do
func (c Bird) Hop() {
fmt.Println("I am a bird,", c.pet.describe(), ": Hops to a different perch")
}
func main() {
dog := Dog{
pet: pet{nLegs: 4, color: "Brown"},
favouriteToy: "Ball",
}
printNoise(dog)
dog.WagTail()
cat := Cat{
pet: pet{nLegs: 4, color: "Tabby"},
favouriteSleepingPlace: "Sofa",
}
printNoise(cat)
cat.ArchBack()
bird := Bird{
pet: pet{nLegs: 2, color: "Rainbow"},
favoritePerch: "Back of Cage",
}
printNoise(bird)
bird.Hop()
}
Yes, you can run methods that are not part of the interface. There were two issues in the code preventing it from running properly.
The function NewDog returns the type Animal. The WagTale method is attached to Dog not Animal which gave an error. The return type has been changed to Dog.
Pointers are not needed in this code and have been removed.
After these adjustments, the code runs and properly and all methods execute as expected.
Link on Go playground: https://play.golang.org/p/LYZJiQND7WW
package main
import (
"fmt"
)
type Animal interface {
MakeNoise()
}
type Dog struct {
color string
}
/* Interface implementation */
func (d Dog) MakeNoise() {
fmt.Println("Bark!")
}
/* End Interface implementation */
func (d Dog) WagTail() {
fmt.Println(d.color + " dog: Wag wag")
}
func NewDog(color string) Dog {
return Dog{color}
}
func main() {
dog := NewDog("Brown")
dog.MakeNoise()
dog.WagTail()
}

Go "polymorphism"

People are saying, Go is not an OO (Object Oriented) language; don't use OO terms on Go. OK, let me describe what I am able to do with OO --
With an OO language, I can make different animals say different things based on their classes:
cat.Say() // miao
sheep.Say() // bahh
cow.Say() // moo
The same is getting the Area() from Shapes.
However, this go demo code made me believe that it is impossible. Included below as Exhibit#1.
Then today, I found this go demo code, which makes it entirely possible. Included below as Exhibit#2.
So my question is, what's fundamentally different between the two, that makes the first one wrong and second one correct?
How to make the first one "works"?
Exhibit#1:
// Credits: hutch
// https://groups.google.com/d/msg/golang-nuts/N4MBApd09M8/0ij9yGHK_8EJ
////////////////////////////////////////////////////////////////////////////
/*
https://groups.google.com/d/msg/golang-nuts/N4MBApd09M8/tOO5ZXtwbhYJ
LRN:
Subtype polymorphism: Not applicable (Go doesn't have subtyping).
Although if you embed a struct A implementing interface X into a struct B,
struct B will implement interface X, and can be used instead of struct A in
places where struct A is expected. So, kind of yes.
Robert Johnstone:
interfaces behave similarly to virtual functions, but they are not identical. See the (following) example program by hutch.
*/
package main
import "fmt"
type A struct {
astring string
}
type B struct {
A
bstring string
}
type Funny interface {
strange()
str() string
}
func (this *A) strange() {
fmt.Printf("my string is %q\n", this.str())
}
func (this *A) str() string {
return this.astring
}
func (this *B) str() string {
return this.bstring
}
func main() {
b := new(B)
b.A.astring = "this is an A string"
b.bstring = "this is a B string"
b.strange()
// Output: my string is "this is an A string"
// Many people familiar with OO (and unfamiliar with Go) will be quite
// surprised at the output of that program.
}
Exhibit#2:
// Credits: https://play.golang.org/p/Zn7TjiFQik
////////////////////////////////////////////////////////////////////////////
/*
Problem (From Polymorphism-Subtype.go):
https://groups.google.com/d/msg/golang-nuts/N4MBApd09M8/tOO5ZXtwbhYJ
LRN: Subtype polymorphism: Not applicable (Go doesn't have subtyping).
Goal:
This is to demo that "polymorphism" is still doable in Go.
*/
package main
import (
"fmt"
)
type Shape interface {
Area() float32
}
type Point struct {
x float32
y float32
}
// Make sure the structs are different sizes so we're sure it'll work with
// all sorts of types
type Circle struct {
center Point
radius float32
}
func (c Circle) Area() float32 {
return 3.1415 * c.radius * c.radius
}
type Rectangle struct {
ul Point
lr Point
}
func (r Rectangle) Area() float32 {
xDiff := r.lr.x - r.ul.x
yDiff := r.ul.y - r.lr.y
return xDiff * yDiff
}
func main() {
mtDict := make(map[string]Shape)
// No problem storing different custom types in the multitype dict
mtDict["circ"] = Circle{Point{3.0, 3.0}, 2.0}
mtDict["rect"] = Rectangle{Point{2.0, 4.0}, Point{4.0, 2.0}}
for k, v := range mtDict {
fmt.Printf("[%v] [%0.2f]\n", k, v.Area())
}
}
/*
$ go run Polymorphism-Shape.go
[circ] [12.57]
[rect] [4.00]
*/
Your two exhibits are doing different things.
In the first one, B has A embedded in it, and B doesn't implement the strange() method itself, so when you call b.strange(), you get the implementation of strange() defined for A. The receiver (this) of the strange method is b.A, not b, so the value b.A.astring is printed. If you wanted strange to print bstring, you would have to define strange for B.
This points out one of the differences between Go and other OO languages: embedding A within B does not mean that B is a "subclass" of A, so an object of type B cannot be used where an object of type A is expected. However, since B inherits the fields and methods of A, any interface that's implemented by A is also implemented by B, and, unless those methods are defined specifically for B, they operate on the A within B, not B itself.
In the second exhibit, you have the Shape interface which is implemented by the types Circle and Rectangle. The element type of your map is Shape, so any type that implements that interface can be an element in the map. When working with a value of an interface type as you are doing in the loop, you can call any method defined in the interface on the value, and the definition corresponding to the actual type of the value will be called.
First of all I would like to discuss the "impossible" part.
import "fmt"
type Animal interface {
Say() string
}
type Cat struct {}
func (cat Cat) Say() string {
return "miao"
}
type Sheep struct {}
func (sheep Sheep) Say() string {
return "bahh"
}
type Cow struct {}
func (cow Cow) Say() string {
return "moo"
}
func main() {
cat := Cat{}
sheep := Sheep{}
cow := Cow{}
fmt.Println(cat.Say())
fmt.Println(sheep.Say())
fmt.Println(cow.Say())
}
This will work exactly as you would expect. So there is a polymorphism in terms of "different structs responding differently to same method".
The intention of Exhibit#1 demonstrates that what Go does is actually similar to Java castings before #Overrides.
Just add the following method to the first example and see how that will work:
func (this B) strange() {
fmt.Printf("my string is %q\n", this.str())
}

How can I mock multiple types when the signature of a concrete method refers to another concrete type, not its interface?

I'm making use of a third party library that doesn't have any interfaces for its classes. I can use them in my structs no problem, but they have side effects that I want to avoid when unit testing.
// Somewhere there are a couple structs, with no interfaces. I don't own the code.
// Each has only one method.
type ThirdPartyEntry struct {}
func (e ThirdPartyEntry) Resolve() string {
// Do some complex stuff with side effects
return "I'm me!"
}
// This struct returns an instance of the other one.
type ThirdPartyFetcher struct {}
func (f ThirdPartyFetcher) FetchEntry() ThirdPartyEntry {
// Do some complex stuff with side effects and return an entry
return ThirdPartyEntry{}
}
// Now my code.
type AwesomeThing interface {
BeAwesome() string
}
// I have a class that makes use of the third party.
type Awesome struct {
F ThirdPartyFetcher
}
func (a Awesome) BeAwesome() string {
return strings.Repeat(a.F.FetchEntry().Resolve(), 3)
}
func NewAwesome(fetcher ThirdPartyFetcher) Awesome {
return Awesome{
F: fetcher,
}
}
func main() {
myAwesome := NewAwesome(ThirdPartyFetcher{})
log.Println(myAwesome.BeAwesome())
}
This works! But I want to write some unit tests, and so I'd like to Mock both the third party structs. To do so I believe I need interfaces for them, but since ThirdPartyFetcher returns ThirdPartyEntrys, I cannot figure out how.
I created a pair of interfaces which match up with the two third party classes. I'd like to then rewrite the Awesome struct and method to use the generic Fetcher interface. In my test, I would call NewAwesome() passing in a testFetcher, a struct which also implements the interface.
type Awesome struct {
F Fetcher
}
func NewAwesome(fetcher Fetcher) Awesome {
return Awesome{
Fetcher: fetcher,
}
}
type Entry interface {
Resolve() string
}
// Double check ThirdPartyEntry implements Entry
var _ Entry = (*ThirdPartyEntry)(nil)
type Fetcher interface {
FetchEntry() Entry
}
// Double check ThirdPartyFetcher implements Fetcher
var _ Fetcher = (*ThirdPartyFetcher)(nil)
I omit the test code because it's not relevant. This fails on the last line shown.
./main.go:49: cannot use (*ThirdPartyFetcher)(nil) (type *ThirdPartyFetcher) as type Fetcher in assignment:
*ThirdPartyFetcher does not implement Fetcher (wrong type for FetchEntry method)
have FetchEntry() ThirdPartyEntry
want FetchEntry() Entry
The signatures are different, even though I already showed that ThirdPartyEntry implements Entry. I believe this is disallowed because to would lead to something like slicing (in the polymorphic sense, not the golang sense). Is there any way for me to write a pair of interfaces? It should be the case that the Awesome class doesn't even know ThirdParty exists - it's abstracted behind the interface and injected when main calls NewAwesome.
It's not very pretty, but one way would be to:
type fetcherWrapper struct {
ThirdPartyFetcher
}
func (fw fetcherWrapper) FetchEntry() Entry {
return fw.ThirdPartyFetcher.FetchEntry()
}
I'd say mocking things that return structs vs interfaces is a relatively common problem without any great solutions apart from a lot of intermediate wrapping.

How to create a method of a structure in golang that is called automatically?

I have to create a something like a substitute of 2 levels of inheritance in golang, i.e.,
in a package, I have a structure(A), which is inherited(embedded as an anonymous field) by another structure(B) in another package, whose object is to be utilized by the "main" package.
Now, I've created an initializer method for the "B" (BPlease) that returns an object of B (say,B_obj). I can call this initializer(BPlease) from my "main" package at the start of the program.
One of the methods of "B" (say, HelloB()), calls a method of "A"(say,HelloA()) during execution, using "B's" object.
But what I really want is, something like a constructor for "A" that can initialize its fields (preferably when B_obj was created in package "main") before "B" calls any methods of "A".
How to achieve this?
I tried creating an initializer(APlease) for "A" as well and called it (BPlease) to get an object of "A" (A_obj). But I found this object useless as I couldn't utilize it to call "A's" method (HelloA()) inside a method of "B" (HelloB()).
It would be great if someone can tell me how to utilize this object (A_obj).
Here's some code to clarify my query:
package A
type A struct { whatever }
func (A_obj *A) HelloA(){performs some operation...} // a method of A()
func APlease() A {
return A{initialize A fields}
}
-------------------------------------------------------------------------------
package B
type B struct {
A
B fields
}
func BPlease() B {
return B{
A_obj := APlease() // useless to me.... how to utilise this?
initialize B fields}
}
func (B_obj *B) HelloB(){ // a method of B{}
call B_obj.HelloA() // valid as A is an anon field in B struct
some other operations // but A's fields are not initialized for B_obj
...}
---------------------------------------------------
package main
import "B"
import "A"
func main(){
B_obj := B.BPlease() // what I want is, calling this should initialize A's fields for B_obj as well so that when HelloB() calls B_obj.HelloA(), it utilises A's field that have been initialized.
}
I cannot pass all field-values as parameters to B_obj as there are a lot of fields, and also, some field values are generated by calling a method of the same structure.
Regardless of anyone's opinion about fighting the language to have inheritance when it doesn't: No, there are no magic methods, like "getter" or "setter" of whatever. Remotely related (magic powers) are perhaps finalizers, but they're surely not going to help in this case.
However, let me suggest to stop coding language X in Go. Just use Go. Go doesn't use "class-like" inheritance, nor a Go programmer (usually) should. Think of Go like a modernized C. There's no much C code out there relying on inheritance. (OK, I know about GObject ;-)
Some meta-remark: "First structure" and "second structure" make it very hard to understand which one is which. Labeling the different things like A, B and C is the tool which make math so powerful.
Is this your question:
You have two type A and B, B embeds A. You want to make sure B is "fully initialized" in the sense of A is also initialized.
Raw sketch:
type A struct { whatever }
type B struct {
A
more stuff
}
func APlease(params for an A) A {
return A{fields set up from params}
}
func BPlease(params forn an A and for an B) B {
return B{
A: APlease(stuff for A),
more: set from params for B,
}
}
Should do this: You can ask for a proper set up B by calling BPlease with the necessary parameters for both, the embedded A and the rest of B.
To expand on Volker's answer a bit, you should be able to call
func BPlease() B {
a_obj := A.APlease() // initialize the fields of A like normal
b_obj := B{} // create a B, whose anonymous fields are not initialized yet
b_obj.A = a_obj // PERHAPS WHAT YOU WANT: copy all a's fields to b's fields.
// if you are relying sending a_obj's address somewhere in
// APlease(), you may be out of luck.
b_obj.field_unique_to_B = "initialized"
return b_obj
}
Now that you can create B objects with fields initialized by APlease(), you can call A's methods on B's objects, and even call A's methods from within B like so:
func (B_obj *B) HelloB(){
// can't call B_obj.HelloA() like you would expect
B_obj.A.HelloA() // this works. Go "promotes" the anonymous field's methods
// and fields to B_obj
// but they don't appear in B_obj, they appear in B_obj.A
fmt.Printf("And hello from B too; %s", B_obj.field_unique_to_B)
}
I will echo Rick-777 here and suggest you stick to go's naming conventions and idioms; NewReader is much easier to read and understand than ReaderPlease.
I contrived an example that I can put on bitbucket if people want. I think it's much easier to read when you are working with real metaphors; also a disclaimer - this is not the best code, but it does some things that answer your question.
file: car/car.go
package car
import "fmt"
type BaseCar struct {
Doors int // by default, 4 doors. SportsCar will have 2 doors
Wheels int
}
func NewBaseCar() BaseCar {
return BaseCar{Wheels: 4, Doors: 4}
}
// this will be used later to show that a "subclass" can call methods from self.BaseCar
func (c *BaseCar) String() string {
return fmt.Sprintf("BaseCar: %d doors, %d wheels", c.Doors, c.Wheels)
}
// this will be promoted and not redefined
func (c *BaseCar) CountDoors() int {
return c.Doors
}
file sportscar/sportscar.go
package sportscar
// You can think of SportsCar as a subclass of BaseCar. But go does
// not have conventional inheritence, and you can paint yourself into
// a corner if you try to force square c++ structures into round go holes.
import ( "../car" ; "fmt" )
type SportsCar struct {
car.BaseCar // here is the anonymous field
isTopDown bool
}
func NewSportsCar() SportsCar {
conv := SportsCar{} // conv.Wheels == 0
conv.BaseCar = car.NewBaseCar() // now conv.Wheels == conv.Doors == 4
conv.isTopDown = false // SportsCar-only field
conv.Doors = 2 // Fewer Doors than BaseCar
return conv
}
// SportsCar only method
func (s *SportsCar) ToggleTop() {
s.isTopDown = !s.isTopDown
}
// "overloaded" string method note that to access the "base" String() method,
// you need to do so through the anonymous field: s.BaseCar.String()
func (s *SportsCar) String() string {
return fmt.Sprintf("Sports%s, topdown: %t", s.BaseCar.String(), s.isTopDown)
}
file main.go
package main
import ( "./car" ; "./sportscar" ; "fmt")
type Stringer interface { // added this complication to show
String() string // that each car calls its own String() method
}
func main() {
boring := car.NewBaseCar()
fancy := sportscar.NewSportsCar()
fmt.Printf(" %s\n", Stringer(&boring))
fmt.Printf("%s\n", Stringer(&fancy))
fancy.ToggleTop()
fmt.Printf("%s\n", Stringer(&fancy))
fmt.Println("BaseCar.CountDoors() method is callable from a SportsCar:", fancy.CountDoors())
}
There are ways to mimic inheritance in Go if this is what you are looking for, see section "Inheritance" in this blog