How do I get the correct Type of the struct using the anonymous field (or superclass)?
I am trying to make this fish describe itself as a cod:
package main
import (
"fmt"
"reflect"
)
type Fish struct {
}
func (self *Fish) WhatAmI() string {
return reflect.TypeOf(self).String()
}
type Cod struct {
Fish
}
func main() {
c := new(Cod)
fmt.Println("I am a", c.WhatAmI())
}
The output I get is:
I am a *main.Fish
What I want is:
I am a *main.Cod
You are getting the correct answer. The answer you want to get is wrong.
In
func (f *Fish) WhatAmI() string {
return reflect.TypeOf(f).String()
}
f
is of type *main.Fish
, it's even declared to be of that type (f *Fish
). Thus it cannot ever be of type *main.Cod
.
The probable source of confusion: The method set of Cod
inherites the method set of its embedded, anonymous field Fish
and doesn't override it. Thus invoking WhatAmI
on an instance of Cod
"delegates" the call to Fish.WhatAmI
, but the receiver is now the embedded field of type *main.Fish
.
Example with overriding the inherited method:
package main
import (
"fmt"
)
type Fish struct {
}
func (f *Fish) WhatAmI() string {
return fmt.Sprintf("%T", f)
}
type Cod struct {
Fish
}
func (c *Cod) WhatAmI() string {
return fmt.Sprintf("%T", c)
}
func main() {
c := new(Cod)
fmt.Println("I am a", c.WhatAmI())
}
Playground
Output:
I am a *main.Cod
For a fairly generic solution, you could separate the WhatAmI
function from the Fish
type and use an empty interface (see Andrew Gerrand's "The Laws of Reflection"), and just check the type on that:
package main
import (
"fmt"
"reflect"
)
type Fish struct {
}
type Cod struct {
Fish
}
func WhatAmI (self interface{}) string {
return reflect.TypeOf(self).String()
}
func main() {
c := new(Cod)
fmt.Println("I am a", WhatAmI(c))
}
Gives:
I am a *main.Cod
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With