Go embedded struct call child method instead parent method -
here sample of go code interface, parent struct , 2 children structs
package main import ( "fmt" "math" ) // shape interface : defines methods type shapeinterface interface { area() float64 getname() string printarea() } // shape struct : standard shape area equal 0.0 type shape struct { name string } func (s *shape) area() float64 { return 0.0 } func (s *shape) getname() string { return s.name } func (s *shape) printarea() { fmt.printf("%s : area %v\r\n", s.name, s.area()) } // rectangle struct : redefine area method type rectangle struct { shape w, h float64 } func (r *rectangle) area() float64 { return r.w * r.h } // circle struct : redefine area , printarea method type circle struct { shape r float64 } func (c *circle) area() float64 { return c.r * c.r * math.pi } func (c *circle) printarea() { fmt.printf("%s : area %v\r\n", c.getname(), c.area()) } // genreric printarea interface func printarea (s shapeinterface){ fmt.printf("interface => %s : area %v\r\n", s.getname(), s.area()) } //main instruction : 3 shapes of each type //store them in slice of shapeinterface //print each area call of 2 methods func main() { s := shape{name: "shape1"} c := circle{shape: shape{name: "circle1"}, r: 10} r := rectangle{shape: shape{name: "rectangle1"}, w: 5, h: 4} listshape := []c{&s, &c, &r} _, si := range listshape { si.printarea() //!! problem witch area method called !! printarea(si) } }
i have results :
$ go run essai_interface_struct.go shape1 : area 0 interface => shape1 : area 0 circle1 : area 314.1592653589793 interface => circle1 : area 314.1592653589793 rectangle1 : area 0 interface => rectangle1 : area 20
my problem call of shape.printarea
call shape.area
method circle , rectangle instead calling circle.area
, rectangle.area
method.
is bug in go ?
thanks help.
actually in example calling shapeinterface.printarea()
works fine in case of circle
because created printarea()
method type circle
. since did not create printarea()
rectangle
type, method of embedded shape
type called.
this not bug, intended working. go not (quite) object oriented language: not have classes , does not have type inheritance; supports similar construct called embedding both on struct
level , on interface
level, , have methods.
what expect called virtual methods: expect printarea()
method call "overridden" area()
method, in go there no inheritance , virtual methods.
the definition of shape.printarea()
call shape.area()
, happens. shape
not know struct , if embedded in, can't "dispatch" method call virtual, run-time method.
the go language specification: selectors describe exact rules followed when evaluating x.f
expression (where f
may method) choose method called in end. key points:
- a selector
f
may denote field or methodf
of typet
, or may refer field or methodf
of nested anonymous field oft
. number of anonymous fields traversed reachf
called depth int
.- for value
x
of typet
or*t
t
not pointer or interface type,x.f
denotes field or method @ shallowest depth int
there suchf
.
going details
circle
in case of circle
: si.printarea()
call circle.printarea()
because created such method:
func (c *circle) printarea() { fmt.printf("%s : area %v\r\n", c.getname(), c.area()) }
in method c.area()
called c
*circle
, method *circle
receiver called exists.
printarea(si)
calls si.area()
. since si
cicle
, there method area()
circle
receiver, invoked no problem.
rectangle
in case of rectangle
si.printarea()
call method shape.printarea()
because did not define printarea()
method rectangle
type (there no method receiver *rectangle
). , implementation of shape.printarea()
method calls shape.area()
not rectangle.area()
- discussed, shape
doesn't know rectangle
. you'll see
rectangle1 : area 0
printed instead of expected rectangle1 : area 20
.
but if call printarea(si)
(passing rectangle
), calls si.area()
rectangle.area()
because such method exists.
Comments
Post a Comment