在这个例子中,我们将强迫开发者使用一个结构类型作为实现特定接口的参数。这个参数将在构造函数中使用,但它也可以作为函数或方法使用。我们这样做的原因是,我们的包能够与某种结构类型一起工作。结构的字段和功能可以是任何东西,只要它满足接口。
我们的例子很简单。有一个挑剔的司机,这个司机只喜欢开 "A "级车。不过,我们要给他提供一切
结构
├── car
│ ├── audi.go
│ └── mercedes.go
├── driver
│ ├── car.go
│ └── driver.go
└── main.go
文件
car.go
package driver
type Car interface {
CheckClass(requiredClass string) bool
Make() string
Model() string
}
司机.go
package driver
import "log"
type Driver struct {
name string
requiredClass string
cars []Car
}
func New(name, requiredClass string, car... Car) Driver {
return Driver{
name: name,
requiredClass: requiredClass,
cars: car,
}
}
func (d Driver) Drive() {
for _, car := range d.cars {
if car.CheckClass(d.requiredClass) {
log.Println(d.name, "will drive", car.Make(), car.Model())
} else {
log.Println(d.name, "won't drive", car.Make(), car.Model())
}
}
}
Audi.go
package car
type Audi struct {
// Class
Cls string
// Model
Mdl string
}
func (c Audi) CheckClass(requiredClass string) bool {
return c.Cls == requiredClass
}
func (c Audi) Make() string {
return "Audi"
}
func (c Audi) Model() string {
return c.Mdl
}
Mercedes.go
package car
type Mercedes struct {
// Class
Cls string
// Model
Mdl string
}
func (c Mercedes) CheckClass(requiredClass string) bool {
return c.Cls == requiredClass
}
func (c Mercedes) Make() string {
return "Mercedes"
}
func (c Mercedes) Model() string {
return c.Mdl
}
主程序
package main
import (
"client/internal/car"
"client/internal/driver"
)
func main() {
merc1 := car.Mercedes{
Cls: "A",
Mdl: "SL500",
}
merc2 := car.Mercedes{
Cls: "C",
Mdl: "D200",
}
audi1 := car.Audi{
Cls: "A",
Mdl: "80",
}
driver.
New("inanzzz", "A", merc1, merc2, audi1).
Drive()
}
测试
2020/04/06 18:01:54 inanzzz will drive Mercedes SL500
2020/04/06 18:01:54 inanzzz won't drive Mercedes D200
2020/04/06 18:01:54 inanzzz will drive Audi 80