Interface үндэс
Interface бол Go-ийн хамгийн хүчирхэг онцлогуудын нэг. Interface нь "энэ struct ямар method-уудтай байх ёстой" гэсэн гэрээ тодорхойлдог. Хэрэв struct тухайн method-уудыг бүгдийг хэрэгжүүлсэн бол тэр interface-г "хэрэгжүүлсэн" гэж үзнэ.
Go-д interface-г тодорхой зарлан хэрэгжүүлдэггүй — struct-ийн method-ууд таарвал автоматаар хэрэгжүүлсэн гэж тооцогдно. Энэ нь Go-ийн гоёмсог дизайны нэг хэсэг юм.
Анхны interface бичих
package main
import (
"fmt"
"math"
)
// Дүрс interface — Талбай() method шаарддаг
type Дүрс interface {
Талбай() float64
}
type Тойрог struct {
Радиус float64
}
type Тэгшөнцөгт struct {
Өргөн float64
Өндөр float64
}
// Тойрог interface хэрэгжүүлж байна
func (т Тойрог) Талбай() float64 {
return math.Pi * т.Радиус * т.Радиус
}
// Тэгшөнцөгт interface хэрэгжүүлж байна
func (т Тэгшөнцөгт) Талбай() float64 {
return т.Өргөн * т.Өндөр
}
func талбайХэвлэх(д Дүрс) {
fmt.Printf("Талбай: %.2f
", д.Талбай())
}
func main() {
тойрог := Тойрог{Радиус: 5}
тэгш := Тэгшөнцөгт{Өргөн: 4, Өндөр: 6}
талбайХэвлэх(тойрог) // Тойрог Дүрс interface-г хэрэгжүүлдэг
талбайХэвлэх(тэгш) // Тэгшөнцөгт ч мөн адил
}
Дэлгэцэнд:
Талбай: 78.54
Талбай: 24.00
талбайХэвлэх функц нь Дүрс interface-г хүлээн авдаг. Талбай() method-той ямар ч struct-г дамжуулж болно. Энэ бол interface-ийн гол давуу тал — нэг функц өөр өөр төрлийн утгуудтай ажиллаж чадна.
Олон method-той interface
Interface нь олон method шаарддаг байж болно:
package main
import "fmt"
// Амьтан interface
type Амьтан interface {
Дуу() string
Нэр() string
}
type Нохой struct {
нэр string
}
type Муур struct {
нэр string
}
func (н Нохой) Дуу() string { return "Хав хав!" }
func (н Нохой) Нэр() string { return н.нэр }
func (м Муур) Дуу() string { return "Миав~" }
func (м Муур) Нэр() string { return м.нэр }
func танилцуул(а Амьтан) {
fmt.Printf("%s хэлнэ: %s
", а.Нэр(), а.Дуу())
}
func main() {
нохой := Нохой{нэр: "Бурхан"}
муур := Муур{нэр: "Цаасан"}
танилцуул(нохой)
танилцуул(муур)
// Slice-д хамт хадгалж болно
амьтад := []Амьтан{нохой, муур}
fmt.Println("
Бүх амьтад:")
for _, а := range амьтад {
танилцуул(а)
}
}
Дэлгэцэнд:
Бурхан хэлнэ: Хав хав!
Цаасан хэлнэ: Миав~
Бүх амьтад:
Бурхан хэлнэ: Хав хав!
Цаасан хэлнэ: Миав~
[]Амьтан slice нь Амьтан interface-г хэрэгжүүлсэн ямар ч struct-г агуулж чадна. Энэ нь маш уян хатан байдлыг бий болгодог.
Хоосон interface — any
Go-д any (эсвэл interface{}) нь ямар ч утгыг хүлээн авдаг хоосон interface юм:
package main
import "fmt"
func юуч(утга any) {
fmt.Printf("Утга: %v, Төрөл: %T
", утга, утга)
}
func main() {
юуч(42)
юуч("Сайн уу")
юуч(3.14)
юуч(true)
юуч([]int{1, 2, 3})
}
Дэлгэцэнд:
Утга: 42, Төрөл: int
Утга: Сайн уу, Төрөл: string
Утга: 3.14, Төрөл: float64
Утга: true, Төрөл: bool
Утга: [1 2 3], Төрөл: []int
%T нь утгын төрлийг хэвлэнэ. any ашигласнаар fmt.Println дурын төрлийг хэвлэж чаддаг шалтгаан тодорхой болно — энэ нь ...any параметртэй.
Дараагийн хичээлд:
Interface-ийн дэвшилтэт хэрэглээг судална — type assertion, type switch болон interface-ийг хэрхэн бодит кодод ашигладаг талаар илүү дэлгэрэнгүй үзнэ.