> For the complete documentation index, see [llms.txt](https://ineelhere.gitbook.io/code-with-go/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ineelhere.gitbook.io/code-with-go/21-interfaces.md).

# Interfaces

This Go program demonstrates the use of interfaces and polymorphism. It defines an interface named `geometry` with methods `area` and `perim`. Two struct types, `rect` and `circle`, implement this interface by providing their own versions of the `area` and `perim` methods. The `measure` function takes a `geometry` interface as a parameter and calls its methods. Finally, in the `main` function, instances of `rect` and `circle` are created, and the `measure` function is called on each of them.

Let's go through each part of the code with inline comments and additional explanations:

```go
package main

import (
    "fmt"
    "math"
)

// Define an interface named 'geometry' with methods 'area' and 'perim'
type geometry interface {
    area() float64
    perim() float64
}

// Define a struct named 'rect' with two fields: 'width' and 'height'
type rect struct {
    width, height float64
}

// Define a struct named 'circle' with a field 'radius'
type circle struct {
    radius float64
}

// Implement the 'area' method for the 'rect' struct
func (r rect) area() float64 {
    return r.width * r.height
}

// Implement the 'perim' method for the 'rect' struct
func (r rect) perim() float64 {
    return 2*r.width + 2*r.height
}

// Implement the 'area' method for the 'circle' struct
func (c circle) area() float64 {
    return math.Pi * c.radius * c.radius
}

// Implement the 'perim' method for the 'circle' struct
func (c circle) perim() float64 {
    return 2 * math.Pi * c.radius
}

// Function 'measure' takes a 'geometry' interface and prints information about it
func measure(g geometry) {
    fmt.Println(g)
    fmt.Println("Area:", g.area())
    fmt.Println("Perimeter:", g.perim())
}

func main() {
    // Create an instance of the 'rect' struct
    r := rect{width: 3, height: 4}

    // Create an instance of the 'circle' struct
    c := circle{radius: 5}

    // Call 'measure' function for the 'rect' instance
    measure(r)

    // Call 'measure' function for the 'circle' instance
    measure(c)
}
```

#### Output

```
{3 4}
12
14
{5}
78.53981633974483
31.41592653589793
```

Explanation:

1. The `geometry` interface is defined with two methods, `area` and `perim`.
2. Two struct types, `rect` and `circle`, implement the `geometry` interface by providing their own versions of the `area` and `perim` methods.
3. The `measure` function takes a parameter of type `geometry` and prints information about it, including calling the `area` and `perim` methods.
4. In the `main` function:
   * An instance of the `rect` struct (`r`) and an instance of the `circle` struct (`c`) are created.
   * The `measure` function is called for both the `rect` and `circle` instances, demonstrating polymorphism. The function can work with any type that implements the `geometry` interface, allowing for flexibility and code reusability.
