Взаимодействията са именувани набори от заглавия на методи.
import (
"fmt"
"math"
)
Ето едно просто взаимодействие за работа с геометрични фигури.
type geometry interface {
area() float64
perim() float64
}
За нашия пример ще осѫществим1 това взаимодействие за видовете
rect (четириъгълник) и circle (кръг).
type rect struct {
width, height float64
}
type circle struct {
radius float64
}
За да осѫществим взаимодействие в Го, просто трябва да осѫществим всички методи, описани във взаимодействието. Тук осѫществяваме геометрията на четиригиъгълниците.
func (r rect) area() float64 {
return r.width * r.height
}
func (r rect) perim() float64 {
return 2*r.width + 2*r.height
}
Осѫществяването за кръгове се състои в следното.
func (c circle) area() float64 {
return math.Pi * c.radius * c.radius
}
func (c circle) perim() float64 {
return 2 * math.Pi * c.radius
}
Ако дадена променлива е обявена като някакъв вид взаимодействие, можем да
извикваме върху нея методите, описани във взаимодействието. Ето една
обобщена1 за всички променливи от вида geometry функция.
func measure(g geometry) {
fmt.Println(g)
fmt.Println(g.area())
fmt.Println(g.perim())
}
Понякога е полезно да знаем сѫщинския вид на дадена променлива по време на изпълнение, която е обявена като вид взаимодействие. Един начин да направим това е като използваме потвърждение на вида1. Друг такъв начин е превключване според вида2.
func detectCircle(g geometry) {
if c, ok := g.(circle); ok {
fmt.Println("кръг с радиус:", c.radius)
}
}
func main() {
r := rect{width: 3, height: 4}
c := circle{radius: 5}
Съставните видове circle and rect осѫществяват (и така правят
възможно) взаимодействието, така че можем да ползваме инстанции от
тези видове като податки на функцията measure.
measure(r)
measure(c)
detectCircle(r)
detectCircle(c)
}
$ go run interfaces.go
{3 4}
12
14
{5}
78.53981633974483
31.41592653589793
кръг с радиус: 5
За да раберете как работят взаимодействията в Го, прочетете тази статия.
Следващ пример: Броители.