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)?
Related
This question already has answers here:
Implement generic linked list in golang which disallows different types in the same linkedlist
(2 answers)
Any type and implementing generic list in go programming language
(2 answers)
Generic Structs with Go
(1 answer)
Closed last month.
The usual linked list structure is as follows:
type IntNode struct {
Value int
Next *IntNode
Pre *IntNode
}
but when i want value to be string, i need another struct:
type StringNode struct {
Value string
Next *StringNode
Pre *StringNode
}
I don't want to use interface{} to reduce the consumption of assertions. Is there a feasible way to write different types through a structure?
Go 1.18 supports generics:
type LLNode[T any] struct {
Value T
Next *LLNode[T]
Prev *LLNode[T]
}
So now you can use:
intList := &LLNode[int]{Value: 1}
stringList := &LLNode[string]{Value: "abcd"}
This question already has answers here:
Can I construct a slice of a generic type with different type parameters?
(2 answers)
Closed 11 days ago.
I want to have a slice of structs with a generic. The generic is an interface with a type constraint.
type constraint interface {
int32 | uint32
}
type a[T constraint] struct {
something T
}
type b struct {
as []a[constraint] // doesn't work
}
How do I make it so i can use both a[int32] and a[uint32] as elements in b.as?
What I am trying to do is not possible in the way I am proposing. This is because a[int32] and a[uint32] are different types. I need to create an internal interface that only a implements and create an array of that.
type internal interface {
someObscureMethod()
}
func (anA a[T]) someObscureMethod() {}
type b struct {
as []internal
}
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.
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(¬MyStruct{})
}
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...
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.