Home > Software engineering >  How to define Golang interface for methods on struct pointer
How to define Golang interface for methods on struct pointer

Time:12-27

For structs, it is possible to define a func that can update struct variables. Is there any way to use those functions in interface?

In the following code, I tried to create a minimal example to describe my question. two struct of Rect and Circle are defined. Both of the structs have Perimeter and Expand functions. Perimeter function calculates the perimeter of the shape. Expand function increases the perimeter of the shape by changing its properties. Also Shape interface with the Perimeter method signature is defined.

viewShapeData function accept input parameter of Shape type. This function view data of the shapes and also run the Perimeter method and view the perimeter of shapes.

package main

import "fmt"

type Shape interface {
    Perimeter() float64
}

type Rect struct {
    width  float64
    height float64
}

type Circle struct {
    radius float64
}

func (s Rect) Perimeter() float64 {
    return 2 * (s.width   s.height)
}

func (s Circle) Perimeter() float64 {
    return 2 * 3.14 * s.radius
}

func (s *Rect) Expand(increaseValue float64) {
    s.width  = increaseValue / 2
}

func (s *Circle) Expand(increaseValue float64) {
    s.radius  = increaseValue / 3.14 / 2
}

func main() {
    a := Circle{radius: 10.0}
    b := Rect{width: 2.4, height: 5}

    a.Expand(1)
    viewShapeData(a)

    b.Expand(1)
    viewShapeData(b)
}

func viewShapeData(s Shape) {
    fmt.Printf("value: %v, Type: %T, Perimeter: %f\n", s, s, s.Perimeter())
}

Now I'm looking for a way to call the Expand method in the viewShapeData function. I tried different ways and applied the following changes in the described code:

type Shape interface {
    Perimeter() float64
    Expand(float64)
}

func main() {
    a := Circle{radius: 10.0}
    b := Rect{width: 2.4, height: 5}

    viewShapeData(a)
    viewShapeData(b)
}

func viewShapeData(s Shape) {
    s.Expand(1)
    fmt.Printf("value: %v, Type: %T, Perimeter: %f\n", s, s, s.Perimeter())
}

But these errors appear:

cannot use a (type Circle) as type Shape in argument to viewShapeData:
        Circle does not implement Shape (Expand method has pointer receiver)
cannot use b (type Rect) as type Shape in argument to viewShapeData:
        Rect does not implement Shape (Expand method has pointer receiver)

Please give me a solution or tell me why Golang does not support this kind of coding.

CodePudding user response:

So, if you want to use a pointer receiver, you also should pass a pointer into the function that takes the interface.

For example

func main() {
    a := Circle{radius: 10.0}
    b := Rect{width: 2.4, height: 5}
    
    a.Expand(1)
    viewShapeData(&a)

    b.Expand(1)
    viewShapeData(&b)
}

https://play.golang.com/p/pmHd5yl_v8p

  • Related