package main
import (
    "fmt"
    "reflect"
)
type Geometry interface {
    Area() float64
    Perimeter() float64
}
/* Square */
type Square struct {
    A float64
}
func (this Square) Area() float64 {
    return this.A * this.A
}
func (this Square) Perimeter() float64 {
    return this.A * 4
}
/* Rectangle */
type Rectangle struct {
    A float64
    B float64
}
func (this Rectangle) Area() float64 {
    return this.A * this.B
}
func (this Rectangle) Perimeter() float64 {
    return (this.A + this.B) * 2
}
func main() {
    square1 := Square{A: 5}
    square2 := Square{A: 10}
    rectangle1 := Rectangle{A: 5, B: 15}
    rectangle2 := Rectangle{A: 7, B: 27}
    geometries := []Geometry{square1, rectangle1, square2, rectangle2}
    for _, geometry := range geometries {
        fmt.Println(reflect.TypeOf(geometry).Name())
        fmt.Printf("Area: %0.2f\n", geometry.Area())
        fmt.Printf("Perimeter: %0.2f\n", geometry.Perimeter())
        fmt.Println("----------------------")
    }
}    
        
Square
Area: 25.00
Perimeter: 20.00      
----------------------
Rectangle
Area: 75.00
Perimeter: 40.00      
----------------------
Square
Area: 100.00
Perimeter: 40.00      
----------------------
Rectangle
Area: 189.00
Perimeter: 68.00      
----------------------