dake 10 éve
szülő
commit
cbdb2d70ce
3 módosított fájl, 218 hozzáadás és 3 törlés
  1. 3 3
      eBook/11.13.md
  2. 214 0
      eBook/11.14.md
  3. 1 0
      eBook/directory.md

+ 3 - 3
eBook/11.13.md

@@ -8,13 +8,13 @@ OO 语言最重要的三个方面分别是:封装,继承和多态,在 Go 
 
 	1)包范围内的:通过标识符首字母小写,`对象`只在它所在的包内可见
 
-	2)可导出的:通过标识符首字母大写,`对象`在所在包以外可见
+	2)可导出的:通过标识符首字母大写,`对象`对所在包以外也可见
 
 类型只拥有自己所在包中定义的方法。
 
-- 继承:用组合实现:内嵌一个(或多个)包含想要行为(字段和方法)的类型;多重继承可以通过内嵌多个类型实现
+- 继承:用组合实现:内嵌一个(或多个)包含想要行为(字段和方法)的类型;多重继承可以通过内嵌多个类型实现
 
-- 多态:用接口实现:某个类型的实例可以赋给它实现的任意接口的变量。类型和接口是松耦合的,并且多重继承可以通过实现多个接口达到。Go 接口不是 Java 和 C# 接口的变体,而且:接口间是不相关的,并且是大规模编程和可适应演进型设计的关键。
+- 多态:用接口实现:某个类型的实例可以赋给它实现的任意接口类型的变量。类型和接口是松耦合的,并且多重继承可以通过实现多个接口实现。Go 接口不是 Java 和 C# 接口的变体,而且:接口间是不相关的,并且是大规模编程和可适应演进型设计的关键。
 
 
 ## 链接

+ 214 - 0
eBook/11.14.md

@@ -1,2 +1,216 @@
 # 结构体,集合和高阶函数
 
+通常你在应用中定义了一个结构体,那么你也可能需要这个结构体的(指针)对象集合,比如:
+
+```go
+type Any interface{}
+type Car struct {
+	Model        string
+	Manufacturer string
+	BuildYear    int
+	// ...
+}
+
+type Cars []*Car
+
+```
+
+我们可以用函数定义所需的功能有争议的事实来使用高阶函数,例如:
+
+1)定义一个通用的 `Process()` 函数,它接收一个作用于每一辆 car 的 f 函数作参数:
+
+```go
+// Process all cars with the given function f:
+func (cs Cars) Process(f func(car *Car)) {
+	for _, c := range cs {
+		f(c)
+	}
+}
+
+```
+
+2)在上面的基础上,实现一个查找函数来获取子集合,并在 `Process()` 中传入一个闭包执行(这样就可以访问局部切片 `cars`):
+
+```go
+// Find all cars matching a given criteria.
+func (cs Cars) FindAll(f func(car *Car) bool) Cars {
+
+	cars := make([]*Car, 0)
+	cs.Process(func(c *Car) {
+			if f(c) {
+                append(cars,c)
+            }
+    )
+	return cars
+}
+
+```
+
+3)实现一个 Map 功能,产出除了 car 对象以外的东西:
+
+```go
+// Process cars and create new data.
+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
+}
+
+```
+
+现在我们可以定义下面这样的具体查询:
+
+```go
+allNewBMWs := allCars.FindAll(func(car *Car) bool {
+       return (car.Manufacturer == “BMW”) && (car.BuildYear > 2010)
+})
+
+```
+
+4)我们也可以根据入参返回不同的函数。也许我们想根据不同的厂商添加汽车到不同的集合,但是这可能会是多变的。所以我们可以定义一个函数来产生特定的添加函数和 map 集:
+
+```go
+funcMakeSortedAppender(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
+}
+
+```
+
+现在我们可以用它来把汽车分为独立的集合,像这样:
+
+```go
+manufacturers := []string{“Ford”, “Aston Martin”, “Land Rover”, “BMW”, “Jaguar”}
+sortedAppender, sortedCars := MakeSortedAppender(manufacturers)
+allUnsortedCars.Process(sortedAppender)
+BMWCount := len(sortedCars[“BMW”])
+
+```
+
+我们让这些代码在下面的程序 cars.go(此外只展示了 main() 中的代码,别的代码已经在上面展示)中执行:
+
+示例 11.18 [cars.go](examples/chapter_11/cars.go):
+
+```go
+// cars.go
+package main
+
+import (
+	"fmt"
+)
+
+
+type Any interface{}
+type Car struct {
+	Model   	string
+	Manufacturer	string
+	BuildYear	int
+    // ...
+}
+type Cars []*Car
+
+func main() {
+	// make some cars:
+	ford := &Car{"Fiesta","Ford", 2008}
+	bmw  := &Car{"XL 450", "BMW", 2011}
+	merc := &Car{"D600", "Mercedes", 2009}
+	bmw2 := &Car{"X 800", "BMW", 2008}
+	// query:
+	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")
+}
+
+// Process all cars with the given function f:
+func (cs Cars) Process(f func(car *Car)) {
+     for _, c := range cs {
+         f(c)
+     }
+}
+
+// Find all cars matching a given criteria.
+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
+}
+
+// Process cars and create new data.
+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) {
+     // 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
+}
+
+/* Output:
+AllCars:  [0xf8400038a0 0xf840003bd0 0xf840003ba0 0xf840003b70]
+New BMWs:  [0xf840003bd0]
+Map sortedCars:  map[Default:[0xf840003ba0] Jaguar:[] Land Rover:[] BMW:[0xf840003bd0 0xf840003b70] Aston Martin:[] Ford:[0xf8400038a0]]
+We have  2  BMWs
+*/
+
+```
+
+
+## 链接
+
+- [目录](directory.md)
+- 上一节:[Go 中的面向对象](11.13.md)
+- 下一章:[读写数据](12.0.md)

+ 1 - 0
eBook/directory.md

@@ -107,6 +107,7 @@
     - 11.11 [Printf 和反射](11.11.md)
     - 11.12 [接口与动态类型](11.12.md)
     - 11.13 [总结:Go 中的面向对象](11.13.md)
+    - 11.14 [结构体,集合和高阶函数](11.14.md)
 
 ## 第三部分:Go 高级编程