Jeff
Jeff

Reputation: 7210

GO using interfaces as fields

I'm going through An Introduction to Programming in Go and trying to grasp interfaces. I feel like I have an ok idea of what they are and why we would need them but I'm having trouble using them. At the end of the section they have

Interfaces can also be used as fields:

type MultiShape struct {
    shapes []Shape
}

We can even turn MultiShape itself into a Shape by giving it an area method:

func (m *MultiShape) area() float64 {
    var area float64
    for _, s := range m.shapes {
        area += s.area()
    }
    return area
}

Now a MultiShape can contain Circles, Rectangles or even other MultiShapes.

I don't know how to use this. My understanding of this is MultiShape can have a Circle and Rectangle in it's slice

This is the example code I'm working with

package main

import ("fmt"; "math")


type Shape interface {
    area() float64
}

type MultiShape struct {
    shapes []Shape
}

func (m *MultiShape) area() float64 {
    var area float64
    for _, s := range m.shapes {
        area += s.area()
    }
    return area
}

// ===============================================
// Rectangles

type Rectangle struct {
    x1, y1, x2, y2 float64
}

func distance(x1, y1, x2, y2 float64) float64 {
    a := x2 - x1
    b := y2 - y1
    return math.Sqrt(a*a + b*b)
}

func (r *Rectangle) area() float64 {
    l := distance(r.x1, r.y1, r.x1, r.y2)
    w := distance(r.x1, r.y1, r.x2, r.y1)
    return l*w
}

// ===============================================
// Circles

type Circle struct {
    x, y, r float64
}

func (c * Circle) area() float64 {
    return math.Pi * c.r*c.r
}

// ===============================================

func totalArea(shapes ...Shape) float64 {
    var area float64
    for _, s := range shapes {
        area += s.area()
    }
    return area
}

func main() {

    c := Circle{0,0,5}
    fmt.Println(c.area())

    r := Rectangle{0, 0, 10, 10}
    fmt.Println(r.area())

    fmt.Println(totalArea(&r, &c))

    //~ This doesn't work but this is my understanding of it
    //~ m := []MultiShape{c, r}
    //~ fmt.Println(totalArea(&m))

}

Can someone help me with this? I have a python background so if there is some kind of link between the two that would help.

Thanks

Upvotes: 2

Views: 269

Answers (1)

peterSO
peterSO

Reputation: 166529

For example,

package main

import (
    "fmt"
    "math"
)

type Shape interface {
    area() float64
}

type MultiShape struct {
    shapes []Shape
}

func (m *MultiShape) area() float64 {
    var area float64
    for _, s := range m.shapes {
        area += s.area()
    }
    return area
}

type Rectangle struct {
    x1, y1, x2, y2 float64
}

func (s *Rectangle) area() float64 {
    x := math.Abs(s.x2 - s.x1)
    y := math.Abs(s.y2 - s.y1)
    return x * y
}

func (s *Rectangle) distance() float64 {
    x := s.x2 - s.x1
    y := s.y2 - s.y1
    return math.Sqrt(x*x + y*y)
}

type Circle struct {
    x, y, r float64
}

func (s *Circle) area() float64 {
    return math.Pi * s.r * s.r
}

func main() {
    r1 := Rectangle{1, 1, 4, 4}
    fmt.Println(r1.area())
    r2 := Rectangle{2, 4, 3, 6}
    fmt.Println(r2.area())
    c := Circle{10, 10, 2}
    fmt.Println(c.area())
    m := MultiShape{[]Shape{&r1, &r2, &c}}
    fmt.Println(m.area())
}

Output:

9
2
12.566370614359172
23.566370614359172

Upvotes: 3

Related Questions