Unexpected behavior in Go structs [duplicate] - go

This question already has answers here:
Golang method with pointer receiver [duplicate]
(2 answers)
Closed 4 years ago.
I faced a strange behavior in Go structs. I might be misunderstanding something but when I created like so:
type ITest interface {
Foo() string
Bar(string)
}
type Base struct {
value string
}
func (b Base) Foo () string {
return b.value
}
func (b *Base) Bar (val string) {
b.value = val
}
// Not implementing ITest
type Sub struct {
Base
}
// Now it works
type Sub struct {
*Base
}
Then Sub is not implementing ITest. But if I change Sub to embed pointer of Base it starts to implement ITest. I know it somehow related to caller in methods but come on. So the question is: Is that me Going wrong or Go have problems with embedding logic?

*Base has a method Bar, but Base does not; so Base does not implement ITest. Thus, embedding a *Base allows Sub to implement the interface.
Your use of the names Base and Sub also implies you may be conflating composition and inheritance, which you should be very careful with in Go. There is no inheritance in Go. There are no base classes, no subclasses, no class hierarchy, no inheritance. The only form of polymorphism in go is interfaces.

Related

golang how to overwrite function like this [duplicate]

This question already has answers here:
Go embedded struct call child method instead parent method
(1 answer)
Can embedded struct method have knowledge of parent/child?
(2 answers)
Ensuring embedded structs implement interface without introducing ambiguity
(2 answers)
What is the idiomatic way in Go to create a complex hierarchy of structs?
(1 answer)
Closed 8 months ago.
I have the following:
type A struct {
}
func (t *A) Do() {
print("A")
}
func (t *A) Display() {
t.Do()
}
type B struct {
A
}
func (t *B) Do() {
print("B")
}
And I will do like this
func TestC(t *testing.T) {
b := new(B)
// it will print "A", I neet it calling B's Do()
b.Display()
}
How to implement this, like java's abstruct class
It might be possible, but this isn't really how Go works. Go doesn't have classes, just structs, and structs can't be inherited, like classes can be. What you're doing here is embedding an A inside B. B then has:
b.Do
b.A.Display
b.A.Do
as it's "methods". There is no B.Display, so b.Do won't be called, because b.A.Display will be called instead.
There's not one specific way to do what you want as an alternative. You likely need to rethink how you would solve this problem. One possible solution is to define an interface, and then type your functions based on that interface. e.g.
type DoDisplay interface {
Do()
Display()
}
func IDo(obj DoDisplay) {
obj.Do()
}
func IDisplay(obj DoDisplay) {
obj.Display()
}
You would still need to define the Display method on B, and it very likely will still be the same as A. Other solutions might be to define a base type, and inject a specific do function to the struct (though I'd say that's a special case and not a recommended practice). Another solution might involve generics. There's also the ability to ask Go to generate code for you for these kinds of scenarios. But, the interface is likely the first thing you should try.

How to check if an interface have a function implementation in Go? [duplicate]

This question already has answers here:
Go reflection with interface embedded in struct - how to detect "real" functions?
(5 answers)
Closed 10 months ago.
I have a constructor that returns an interface. There are cases when that interface does not have actual implementation of some of its functions. Trying to call these unemplemented functions causes panic. I want to know is there a way to check is it safe to call a function or not, before actually calling it.
Here is the setup.
package main
type i interface {
Foo()
Bar()
}
type s struct {
i
}
func (r s) Foo() {}
func main() {
var ii i = &s{}
ii.Foo() // OK
ii.Bar() // will panic
}
The type s embeds an interface variable. Any call to interface methods not explicitly declared by s will panic because the embedded interface is nil. You should set that before calling the methods:
var ii i=&s{}
ii.i=<implementation of i>
So, it is not that the type s unimplemented methods. The type s delegates its method implementations to i, which is nil.

Golang - handle structs polymorphically [duplicate]

This question already has answers here:
Understanding polymorphism in Go
(2 answers)
Embedded types and polymorphism with structs
(2 answers)
Polymorphism in Go - does it exist?
(4 answers)
Multiple Struct switch?
(2 answers)
Closed 10 months ago.
I wish to use multiple structs which inherits from the same Base struct in a polymorphic manner.
Given those structs:
type Base struct { X bool }
type A struct {
Base // inherit Base
A bool
}
type B struct {
Base // inherit Base
B bool
}
I would like to pass either of those structs as an argument to a function polymorphically, and maybe read (or update) one of the Base struct fields:
func CheckIfX(base *Base) bool { // supposed to be a polymorphic function..
return base.X
}
b := &B{
Base{
X: true,
},
B: true,
}
CheckIfX(b) // fail with error..
What I have tried up until now:
Using interface{} and dynamic parsing within the function
(link to playground)
Make structs inherit from an interface
(link to playground).
Drawbacks:
No actual need of implementing methods on my use case, so feels like an overkill
Structs wont parse as expected (for example when trying to save on Firestore..)
I would also like to ask:
Lets say we couldn't come up with something better than dynamic parsing,
would you consider it a better practice than simply use 2 (or more) separet functions (rather than forcing it on a single one)?

Golang – Testing for interface implementation of underlying value? [duplicate]

This question already has answers here:
How to known a function of a interface is not realized? [duplicate]
(1 answer)
Go reflection with interface embedded in struct - how to detect "real" functions?
(5 answers)
Closed 2 years ago.
So, I was trying to find the solution via the search and web-search. Wasn't successful.
This has likely a simple solution, but probably I'm just a bit messed up.
I have prepared the following example in go playground.
// main.go
type myInterface interface {
Function1() string
Function2() int
}
type notMyStruct struct {
myInterface
// arbitrary implementation
}
func myFunc(val myInterface) {
fmt.Printf("%T %v", val, val)
fmt.Printf("this failes: %q", val.Function1())
// how to safely test,
// whether the underlying value
// has implemented the interface?
}
func main() {
myFunc(&notMyStruct{})
}
It consists of an interface myInterface, an arbitrary struct notMyStruct, which has the embedded interface (but not actually implemented) and some other arbitrary fields.
Now this struct is injected into myFunc, which the go compiler will accept, due to the fact that the interface is embedded.
But if myFunc tries to call a Function of the interface, it panics – understandably.
Assuming, I don't know the actual struct implementation (because I'm not in control of the interface-implementing code):
How can I reliably test, whether a given underlying value has an actual implementation of the method set (Function1 and Function2) defined by the interface?
I assume, this is solvable with reflect package (performance is not an issue here). Maybe there's any other solutions thinkable? Type assertion didn't seem to work out for me...

Circular import with structs [duplicate]

This question already has answers here:
Registering packages in Go without cyclic dependency
(2 answers)
Closed 7 years ago.
I have a project with several modules in Go. I am having problem with circular imports because of the scenario below:
Details
A module Game contains a struct with the current Game state. Another module (Modifier) is doing some game specific stuff and calculations and therefore modifies the game state. Because of this, Modifier will need the struct Game, but not any methods from Game. Modifier is called from Game and here we have the circular import.
Problem:
Game initiates Modifier
Modifier needs Game struct
It seems to me that this is a common scenario, so I wonder how I should solve it in the best way. My solution would be to create a third module "Structs" which just contains all the structs for the whole application. Is this a good solution?
With the 3rd package option:
yourgame/
state/
state.go
modifier/
modifier.go
main.go
main.go would glue the two components together:
import "yourgame/state"
import "yourgame/modifier"
type Game struct {
state state.State
modifier modifier.Modifier
}
func main() {
// something like:
var game Game
game.modifier.Modify(game.state)
}
This approach is probably too tightly coupled though. Rather than manipulating an essentially global state object, I would try to slice up the data into just what you need for the modifier.
Reasoning in the abstract is hard, so here's a concrete example of what I mean. In your game:
type Object struct {
ID, X, Y int
// more data here
}
type Game struct {
Objects map[int]*Object
}
In your "modifier", let's suppose we had an AI module that moves an object. If all he cares about is the position of a single object you can create an interface:
// in yourgame/modifier
type Object interface {
GetCoordinates() (int, int)
SetCoordinates(int, int)
}
type Modifier struct {}
func (m *Modifier) Update(obj Object) { }
Then we just have to add those methods to our original Object:
type (obj *Object) GetCoordinates() (int, int) {
return obj.X, obj.Y
}
type (obj *Object) SetCoordinates(x, y int) {
obj.X, obj.Y = x, y
}
And now you can pass objects to your modifier without needing a cyclic dependency.
Now if it turns out your "modifier" interface ends up looking almost exactly the same as your game object, then a 3rd package of structs is probably reasonable so you aren't always repeating yourself. For an example consider net/url.
Normally if package B has code that directly reads/modifies A.Type then that code should be in package A.
At least the parts of it if that need direct access should.
To split something between separate packages A and B you'd normal try to isolate an API for access to A.Type that can be expressed as an interface. Then B would define and use this interface and A.Type would implement it (implicitly, without needing to include B's definition of it).
Then something (possibly A, possibily a separate package) would use B by passing an A.Type or *A.Type value as appropriate.
Or depending on your design the relationship could be reversed, with B.OtherType implicitly implementing an interface defined and used by A.
Or both A and B could use each other only through interfaces; it all depends on the details.
E.g. perhaps something like:
package Game // "A"
type State struct {
data int // etc
}
func (s State) IsValid() bool { return true }
func (s *State) ChangeY(arg int) error { return nil }
// …etc…
and:
package Modifier // "B"
type GameState interface {
IsValid() bool
ChangeY(int) error
}
type M struct {
s GameState
//…
}
func New(s GameState) *M {
return &M{s: s}
}
func (m M) DoSomething() {
if s.IsValid() {
// …
}
s.ChangeY(42)
// …etc…
}
I'd define type(Game in this case) and all its methods in same one package. You can't even define methods on type imported from another package according to language spec,
//you should first do
type MyPackageType ImportedType
//and only then
func (foo MyPackageType) Modify() {
...
}

Resources