Programowanie w Go - #11 Interfejsy, pusty interfejs
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 z filmu bez użycia interfejsów.] (#przykład-bez-użycia-interfejsu)
- [Przykład z filmu z użyciem interfejsów] (#przykład-z-filmu-z-użyciem-interfejsów)
- [Przykład z filmu z życiem pustego interfejsu] (#przykład-z-użyciem-pustego-interfejsu)
- [Przykład z wykorzystaniem type assertion na pustym interfejsie] (#przykład-z-wykorzystaniem-type-assertion-na-pustym-interfejsie)
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 :-(")
}
}