|
@@ -1,4 +1,4 @@
|
|
|
-# 结构体、集合和高阶函数
|
|
|
|
|
|
|
+# 11.14 结构体、集合和高阶函数
|
|
|
|
|
|
|
|
通常你在应用中定义了一个结构体,那么你也可能需要这个结构体的(指针)对象集合,比如:
|
|
通常你在应用中定义了一个结构体,那么你也可能需要这个结构体的(指针)对象集合,比如:
|
|
|
|
|
|
|
@@ -48,13 +48,13 @@ func (cs Cars) FindAll(f func(car *Car) bool) Cars {
|
|
|
```go
|
|
```go
|
|
|
// Process cars and create new data.
|
|
// Process cars and create new data.
|
|
|
func (cs Cars) Map(f func(car *Car) Any) []Any {
|
|
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
|
|
|
|
|
|
|
+ result := make([]Any, 0)
|
|
|
|
|
+ ix := 0
|
|
|
|
|
+ cs.Process(func(c *Car) {
|
|
|
|
|
+ result[ix] = f(c)
|
|
|
|
|
+ ix++
|
|
|
|
|
+ })
|
|
|
|
|
+ return result
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
@@ -62,7 +62,7 @@ func (cs Cars) Map(f func(car *Car) Any) []Any {
|
|
|
|
|
|
|
|
```go
|
|
```go
|
|
|
allNewBMWs := allCars.FindAll(func(car *Car) bool {
|
|
allNewBMWs := allCars.FindAll(func(car *Car) bool {
|
|
|
- return (car.Manufacturer == "BMW") && (car.BuildYear > 2010)
|
|
|
|
|
|
|
+ return (car.Manufacturer == "BMW") && (car.BuildYear > 2010)
|
|
|
})
|
|
})
|
|
|
```
|
|
```
|
|
|
|
|
|
|
@@ -84,7 +84,7 @@ func MakeSortedAppender(manufacturers[]string)(func(car*Car),map[string]Cars) {
|
|
|
sortedCars["Default"] = append(sortedCars["Default"], c)
|
|
sortedCars["Default"] = append(sortedCars["Default"], c)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ }
|
|
|
return appender, sortedCars
|
|
return appender, sortedCars
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
@@ -112,23 +112,23 @@ import (
|
|
|
|
|
|
|
|
type Any interface{}
|
|
type Any interface{}
|
|
|
type Car struct {
|
|
type Car struct {
|
|
|
- Model string
|
|
|
|
|
- Manufacturer string
|
|
|
|
|
- BuildYear int
|
|
|
|
|
- // ...
|
|
|
|
|
|
|
+ Model string
|
|
|
|
|
+ Manufacturer string
|
|
|
|
|
+ BuildYear int
|
|
|
|
|
+ // ...
|
|
|
}
|
|
}
|
|
|
type Cars []*Car
|
|
type Cars []*Car
|
|
|
|
|
|
|
|
func main() {
|
|
func main() {
|
|
|
// make some cars:
|
|
// make some cars:
|
|
|
- ford := &Car{"Fiesta","Ford", 2008}
|
|
|
|
|
- bmw := &Car{"XL 450", "BMW", 2011}
|
|
|
|
|
|
|
+ ford := &Car{"Fiesta", "Ford", 2008}
|
|
|
|
|
+ bmw := &Car{"XL 450", "BMW", 2011}
|
|
|
merc := &Car{"D600", "Mercedes", 2009}
|
|
merc := &Car{"D600", "Mercedes", 2009}
|
|
|
bmw2 := &Car{"X 800", "BMW", 2008}
|
|
bmw2 := &Car{"X 800", "BMW", 2008}
|
|
|
// query:
|
|
// query:
|
|
|
allCars := Cars([]*Car{ford, bmw, merc, bmw2})
|
|
allCars := Cars([]*Car{ford, bmw, merc, bmw2})
|
|
|
allNewBMWs := allCars.FindAll(func(car *Car) bool {
|
|
allNewBMWs := allCars.FindAll(func(car *Car) bool {
|
|
|
- return (car.Manufacturer == "BMW") && (car.BuildYear > 2010)
|
|
|
|
|
|
|
+ return (car.Manufacturer == "BMW") && (car.BuildYear > 2010)
|
|
|
})
|
|
})
|
|
|
fmt.Println("AllCars: ", allCars)
|
|
fmt.Println("AllCars: ", allCars)
|
|
|
fmt.Println("New BMWs: ", allNewBMWs)
|
|
fmt.Println("New BMWs: ", allNewBMWs)
|
|
@@ -137,58 +137,58 @@ func main() {
|
|
|
sortedAppender, sortedCars := MakeSortedAppender(manufacturers)
|
|
sortedAppender, sortedCars := MakeSortedAppender(manufacturers)
|
|
|
allCars.Process(sortedAppender)
|
|
allCars.Process(sortedAppender)
|
|
|
fmt.Println("Map sortedCars: ", sortedCars)
|
|
fmt.Println("Map sortedCars: ", sortedCars)
|
|
|
- BMWCount := len(sortedCars["BMW"])
|
|
|
|
|
|
|
+ BMWCount := len(sortedCars["BMW"])
|
|
|
fmt.Println("We have ", BMWCount, " BMWs")
|
|
fmt.Println("We have ", BMWCount, " BMWs")
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Process all cars with the given function f:
|
|
// Process all cars with the given function f:
|
|
|
func (cs Cars) Process(f func(car *Car)) {
|
|
func (cs Cars) Process(f func(car *Car)) {
|
|
|
- for _, c := range cs {
|
|
|
|
|
- f(c)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ for _, c := range cs {
|
|
|
|
|
+ f(c)
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Find all cars matching a given criteria.
|
|
// Find all cars matching a given criteria.
|
|
|
func (cs Cars) FindAll(f func(car *Car) bool) Cars {
|
|
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
|
|
|
|
|
|
|
+ cars := make([]*Car, 0)
|
|
|
|
|
+
|
|
|
|
|
+ cs.Process(func(c *Car) {
|
|
|
|
|
+ if f(c) {
|
|
|
|
|
+ cars = append(cars, c)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ return cars
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Process cars and create new data.
|
|
// Process cars and create new data.
|
|
|
func (cs Cars) Map(f func(car *Car) Any) []Any {
|
|
func (cs Cars) Map(f func(car *Car) Any) []Any {
|
|
|
- result := make([]Any, len(cs))
|
|
|
|
|
- ix := 0
|
|
|
|
|
- cs.Process(func(c *Car) {
|
|
|
|
|
- result[ix] = f(c)
|
|
|
|
|
- ix++
|
|
|
|
|
- })
|
|
|
|
|
- return result
|
|
|
|
|
|
|
+ result := make([]Any, len(cs))
|
|
|
|
|
+ ix := 0
|
|
|
|
|
+ cs.Process(func(c *Car) {
|
|
|
|
|
+ result[ix] = f(c)
|
|
|
|
|
+ ix++
|
|
|
|
|
+ })
|
|
|
|
|
+ return result
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func MakeSortedAppender(manufacturers []string) (func(car *Car), map[string]Cars) {
|
|
func MakeSortedAppender(manufacturers []string) (func(car *Car), map[string]Cars) {
|
|
|
- // Prepare maps of sorted cars.
|
|
|
|
|
- sortedCars := make(map[string]Cars)
|
|
|
|
|
-
|
|
|
|
|
- for _, m := range manufacturers {
|
|
|
|
|
- sortedCars[m] = make([]*Car, 0)
|
|
|
|
|
- }
|
|
|
|
|
- sortedCars["Default"] = make([]*Car, 0)
|
|
|
|
|
-
|
|
|
|
|
- // Prepare appender function:
|
|
|
|
|
- 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
|
|
|
|
|
|
|
+ // Prepare maps of sorted cars.
|
|
|
|
|
+ sortedCars := make(map[string]Cars)
|
|
|
|
|
+
|
|
|
|
|
+ for _, m := range manufacturers {
|
|
|
|
|
+ sortedCars[m] = make([]*Car, 0)
|
|
|
|
|
+ }
|
|
|
|
|
+ sortedCars["Default"] = make([]*Car, 0)
|
|
|
|
|
+
|
|
|
|
|
+ // Prepare appender function:
|
|
|
|
|
+ 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
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|