>

Reflection

If you haven’t already, I’d highly recommend my interface and struct first.

Animal, Dog & Cat

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
type Animal interface {
    Name() string
    Sound() string
}

type Dog struct {
    name string
}
func (d *Dog) Name() string {
    return d.name
}
func (d *Dog) Sound() string {
    return "woof"
}
func (d *Dog) Custom() string {
    return "mailman? woof! woof! woof!"
}

type Cat struct {
    name string
}
func (c *Cat) Name() string {
    return c.name
}
func (c *Cat) Sound() string {
    return "meow"
}

Now, the difference between my interface example, and the above is Dog has a Custom function…

BUT

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import (
    "fmt"
    "reflect"
)

func main() {
    var a Animal = &Dog{name: "Spot"}

    fmt.Printf("%s says %s\n", a.Name(), a.Sound())

    // We can't use Dog.Custom until we convert the Animal
    // BUT, let's pretend we didn't know a's type was *Dog
    switch (reflect.TypeOf(a).Name()) { // Reflect the type of a, and get it's name
        case "*Dog": // If it's a Pointer to a Dog
            var d *Dog = a.(*Dog) // Convert
            fmt.Println(d.Custom())
        default: // It's something else
            fmt.Printf("Not a *Dog, it's a '%s'\n", reflect.TypeOf(a).Name())
    }
}

2023-11-09