翻译11.14

This commit is contained in:
dake
2015-11-02 23:32:53 +08:00
parent 858170db37
commit cbdb2d70ce
3 changed files with 218 additions and 3 deletions

View File

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

View File

@@ -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)

View File

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