Nadszedł czas na spotkanie z interfejsami w Go. Jak programowałeś wcześniej w Javie czy C#, koncept możesz kojarzyć. Jednak działanie interfejsów w Go jest trochę odmienne i warto się temu dokładnie przyjrzeć.

Same interfejsy, to według popularnych opinii jedna z większych zalet języka. Zatem tutaj przedstawię kwestię interfejsów w Go i pokażę jakiś życiowy przykład użycia.

W tym artykule dostępne są kody źródłowe następujących przykładów:

Przykład bez użycia interfejsu


package main

import "fmt"

type Car struct{}

func (c Car) Drive() {
	fmt.Println("Car is driving (forward or backward)!")
}

func (c Car) Break() {
	fmt.Println("Car is suddenly breaking!")
}

func (c Car) Turn() {
	fmt.Println("Car is turning")
}

type Truck struct{}

func (t Truck) Drive() {
	fmt.Println("Truck is driving (forward or backward)!")
}

func (t Truck) Break() {
	fmt.Println("Truck is suddenly breaking!")
}

func (t Truck) Turn() {
	fmt.Println("Truck is turning")
}

type Bicycle struct{}

func (b Bicycle) Drive() {
	fmt.Println("Bicycle is driving!")
}

func (b Bicycle) Break() {
	fmt.Println("Bicycle is breaking!")
}

func (b Bicycle) Turn() {
	fmt.Println("Bicycle is turning")
}

func DoSomethingWithVehicle(c Car, t Truck, b Bicycle) {
	
}

func main() {
	c := Car{}
	t := Truck{}
	b := Bicycle{}

	c.Drive()
	t.Drive()
	b.Drive()
}

Przykład z filmu z użyciem interfejsów

package main

import "fmt"

type Vehicle interface {
	Drive()
	Break()
	Turn()
}

type PetrolVehicle interface {
	Refuel()
}

func DriveVehicle(v Vehicle) {
	v.Drive()
	v.Turn()
	v.Break()
}

func RefuelVehicle(pv PetrolVehicle) {
	pv.Refuel()
}

type Car struct{}

func (c Car) Drive() {
	fmt.Println("Car is driving (forward or backward)!")
}

func (c Car) Break() {
	fmt.Println("Car is suddenly breaking!")
}

func (c Car) Turn() {
	fmt.Println("Car is turning")
}

func (c Car) Refuel() {
	fmt.Println("Car is refueling")
}

type Truck struct{}

func (t Truck) Drive() {
	fmt.Println("Truck is driving (forward or backward)!")
}

func (t Truck) Break() {
	fmt.Println("Truck is suddenly breaking!")
}

func (t Truck) Turn() {
	fmt.Println("Truck is turning")
}

func (t Truck) Refuel() {
	fmt.Println("Truck is Refueling")
}

type Bicycle struct{}

func (b Bicycle) Drive() {
	fmt.Println("Bicycle is driving!")
}

func (b Bicycle) Break() {
	fmt.Println("Bicycle is breaking!")
}

func (b Bicycle) Turn() {
	fmt.Println("Bicycle is turning")
}

func main() {
	c := Car{}
	t := Truck{}
	b := Bicycle{}

	DriveVehicle(c)
	DriveVehicle(t)
	DriveVehicle(b)
	RefuelVehicle(c)
	RefuelVehicle(t)
}

Przykład z użyciem pustego interfejsu

package main

import "fmt"

func main() {
	var a interface{} = 5
	var b interface{} = 4.999
	var c interface{} = "this is string"
	var d interface{} = false
	e := []interface{}{1, "string", false, true, 1.999, []int{1, 2, 3}}
	fmt.Println(a)
	fmt.Println(b)
	fmt.Println(c)
	fmt.Println(d)
	fmt.Println(e)
}

Przykład z wykorzystaniem type assertion na pustym interfejsie

package main

import "fmt"

func main() {
        var i interface{} = false

        switch i.(type) {
        case nil:
                fmt.Println("typ to nil")
        case int:
                fmt.Println("typ to int")
        case string:
                fmt.Println("typ to string")
        case float64:
                fmt.Println("typ to float64")
        default:
                fmt.Println("doprawdy nie wiem co to za typ :-(")
        }

}