17. Go - Interfaces

Interfaces allow values to have/belong to more than one type.
// "if you have these methods, you are my type"

package main

import "fmt"

type species interface {
    addage(a int)
}

type human struct {
    name string
    age  int
}

type baboon struct {
    name string
    age  int
}

func (h *human) addage(a int) {
    h.age = h.age * a
}

func (b *baboon) addage(a int) {
    b.age = b.age * a
}

func main() {
    peter := &human{
        name: "peter",
        age:  20,
    }

    bob := &baboon{
        name: "ad",
        age:  1,
    }

    peter.addage(5)
    bob.addage(5)

    list := []species{
        peter,
        bob,
    }

    fmt.Println(list[0])
}

Interfaces is a type that lets you hold multiple structs that has exactly similar methods. 

This allows easy storing of struct types.


Methods must be exactly the same between structs.

If the method has a pointer receiver for the struct, the variable defined as the struct must have a pointer reference.

Ex:

dog := &animal{} // works

dog := animal{} // doesnt work


If the method has no pointer receiver for the struct, then the variable does not need to have a pointer reference when declared.

Ex:

dog := animal{} // works fine


Can use switch case in a method/function to do stuff to interface objects:

// argument for giveInfo could also be an empty interface: s interface{}

package main

import "fmt"

type humana struct {
    name string
    age  int
}

type doge struct {
    name string
    age  int
}

type speciess interface {
    info()
}

func (d doge) info() {

}

func (h humana) info() {

}

func giveInfo(s speciess) {
    switch s.(type) {
    case doge:
        fmt.Println("DOG")
    case humana:
        fmt.Println("HUMAN")
    default:
        fmt.Println("NONE")
    }
}

func main() {
    brownDog := doge{
        name: "riley",
        age:  5,
    }

    tallHuman := humana{
        name: "Todd",
        age:  1,
    }

    giveInfo(brownDog)
    giveInfo(tallHuman)
}


func giveInfo(s interface{}) {
    switch s.(type) {
    case doge:
        fmt.Println("DOG")
    case humana:
        fmt.Println("HUMAN")
    default:
        fmt.Println("NONE")
    }
}


Using assertion with dot notation:

// doge is asserted, we are knowingly asserting that variable s interface is the type of doge.

// if we dont know, we can get a return by using: s.(type)

fmt.Println(s.(doge).name)


Comments

Popular posts from this blog

2. FreeCodeCamp - Dynamic Programming - Learn to Solve Algorithmic Problems & Coding Challenges

20. Data Analytics - Analyze Data to Answer Questions - Week 1

3. Algorithms - Selection Sort