在应用中定义了一个结构体,可能需要这个结构体的对象集合,例如:
type Any interface{}
type Car struct{
Model string
Manufacturer string
BuildYear int
}
type Cars []*Car
我们可以使用高阶函数,即把函数作为定义所需方法的参数。
func (cs Cars) Process(f func(car *Car)){
for _,c := range cs{
f(c)
}
}
在上面基础上,实现一个查询函数来获取子集,并在 Process( ) 中传入一个闭包执行:
func (cs Cars) FindAll(f func(car *Car) bool) Cars{
cars := make([]*Car,0)
cs.Process(func(c *Car) {
if f(c){
cars = append(cars,c)
}
})
return cars
}
实现 Map 功能,产出除 car 对象以外的东西:
func (cs Cars) Map(f func(car *Car) Any ) []Any{
result := make([]Any,0)
ix := 0
cs.Process(func(c *Car){
result[ix] = f(c)
ix++
})
return result
}
我们可以定义下面这样的具体查询:
allNewBMWs := allCars.FindAll(func(car *Car)bool{
return (car.Manufacturer == "BMW") && (car.BuildYear > 2010)
})
我们可以根据参数返回不同的函数,也许我们向根据不同的厂商添加汽车到不同的集合,但是这可能是变化的。所以我们可以定义一个函数来产生特定的添加函数和 map 集:
func MakeSortedAppender(manufacturers []string)(func(car *Car),map[string]Cars){
sortedCars := make(map[string]Cars)
for _,m := range manufacturers{
sortedCars[m] = make([]*Car,0)
}
sortedCars["Default"] = make([]*Car,0)
appender := func(c *Car){
if _,ok := sortedCars[c.Manufacturer]; ok{
sortedCars[c.Manufacturer] = append(sortedCars[c.Manufacturer],c)
}else{
sortedCars["Default"] = append(sortedCars["Default"],c)
}
}
return appender,sortedCars
}
然后可以用它把汽车分类为独立的集合:
manufacturers := []string{"Ford","Aston Martin","Land Rover","BMW","Jaguar"}
sortedAppender,sortedCars := MakeSortedAppender(manufacturers)
allUnsortedCars.Process(sortedAppender)
BMWCount := len(sortedCars["BMW"])
完整代码
package main
import "fmt"
type Any interface{}
type Car struct{
Model string
Manufacturer string
BuildYear int
}
type Cars []*Car
func (cs Cars) Process(f func(car *Car)){
for _,c := range cs{
f(c)
}
}
func print(car *Car){
fmt.Println(1,car)
}
func (cs Cars) FindAll(f func(car *Car) bool) Cars{
cars := make([]*Car,0)
cs.Process(func(c *Car) {
if f(c){
cars = append(cars,c)
}
})
return cars
}
func (cs Cars) Map(f func(car *Car) Any ) []Any{
result := make([]Any,0)
ix := 0
cs.Process(func(c *Car){
result[ix] = f(c)
ix++
})
return result
}
func MakeSortedAppender(manufacturers []string)(func(car *Car),map[string]Cars){
sortedCars := make(map[string]Cars)
for _,m := range manufacturers{
sortedCars[m] = make([]*Car,0)
}
sortedCars["Default"] = make([]*Car,0)
appender := func(c *Car){
if _,ok := sortedCars[c.Manufacturer]; ok{
sortedCars[c.Manufacturer] = append(sortedCars[c.Manufacturer],c)
}else{
sortedCars["Default"] = append(sortedCars["Default"],c)
}
}
return appender,sortedCars
}
func main() {
ford := &Car{"Fiesta","Ford",2008}
bmw := &Car{"XL 450","BMW",2011}
merc := &Car{"D600","Mercedes",2009}
bmw2 := &Car{"X 800","BMW",2008}
allCars := Cars([]*Car{ford,bmw,merc,bmw2})
allNewBMWs := allCars.FindAll(func(car *Car)bool{
return (car.Manufacturer == "BMW") && (car.BuildYear > 2010)
})
fmt.Println("AllCars:",allCars)
fmt.Println("New BMWs:",allNewBMWs)
manufacturers := []string{"Ford","Aston Martin","Land Rover","BMW","Jaguar"}
sortedAppender,sortedCars := MakeSortedAppender(manufacturers)
allCars.Process(sortedAppender)
fmt.Println("Map sortedCars:",sortedCars)
BMWCount := len(sortedCars["BMW"])
fmt.Println("We have ",BMWCount,"BMWs")
}
输出结果:
AllCars: [0xc000064180 0xc0000641b0 0xc0000641e0 0xc000064210]
New BMWs: [0xc0000641b0]
Map sortedCars: map[Aston Martin:[] BMW:[0xc0000641b0 0xc000064210] Default:[0xc0000641e0] Ford:[0xc000064180] Jaguar:[] Land Rover:[]]
We have 2 BMWs
代码下载
以上程序代码均已上传到至github,有需要可直接进行下载