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 method f of type t, or may refer field or method f of nested anonymous field of t. number of anonymous fields traversed reach f called depth in t.
  • for value x of type t or *t t not pointer or interface type, x.f denotes field or method @ shallowest depth in t there such f.

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

Popular posts from this blog

javascript - AngularJS custom datepicker directive -

javascript - jQuery date picker - Disable dates after the selection from the first date picker -