Browse Source

fix encoding

Unknown 3 years ago
parent
commit
d977e88e8a
10 changed files with 218 additions and 218 deletions
  1. 6 6
      eBook/11.0.md
  2. 52 52
      eBook/11.1.md
  3. 7 7
      eBook/11.2.md
  4. 17 17
      eBook/11.3.md
  5. 16 16
      eBook/11.4.md
  6. 12 12
      eBook/11.5.md
  7. 22 22
      eBook/11.6.md
  8. 34 34
      eBook/11.7.md
  9. 11 11
      eBook/11.8.md
  10. 41 41
      eBook/11.9.md

+ 6 - 6
eBook/11.0.md

@@ -1,9 +1,9 @@
1
-# 11 接口(Interfaces)与反射(reflection)
1
+# 11 接口(Interfaces)与反射(reflection)
2 2
 
3
-本章介绍 Go 语言中接口和反射的相关内容。
3
+本章介绍 Go 语言中接口和反射的相关内容。
4 4
 
5
-## 链接
5
+## 閾炬帴
6 6
 
7
-- [目录](directory.md)
8
-- 上一节:[垃圾回收和SetFinalizer](10.8.md)
9
-- 下一节:[接口是什么](11.1.md)
7
+- [鐩�綍](directory.md)
8
+- 涓婁竴鑺傦細[鍨冨溇鍥炴敹鍜孲etFinalizer](10.8.md)
9
+- 涓嬩竴鑺傦細[鎺ュ彛鏄�粈涔圿(11.1.md)

File diff suppressed because it is too large
+ 52 - 52
eBook/11.1.md


+ 7 - 7
eBook/11.2.md

@@ -1,8 +1,8 @@
1
-# 11.2 接口嵌套接口
1
+# 11.2 接口嵌套接口
2 2
 
3
-一个接口可以包含一个或多个其他的接口,这相当于直接将这些内嵌接口的方法列举在外层接口中一样。
3
+一个接口可以包含一个或多个其他的接口,这相当于直接将这些内嵌接口的方法列举在外层接口中一样。
4 4
 
5
-比如接口 `File` 包含了 `ReadWrite` 和 `Lock` 的所有方法,它还额外有一个 `Close()` 方法。
5
+比如接口 `File` 包含了 `ReadWrite` 和 `Lock` 的所有方法,它还额外有一个 `Close()` 方法。
6 6
 
7 7
 ```go
8 8
 type ReadWrite interface {
@@ -22,8 +22,8 @@ type File interface {
22 22
 }
23 23
 ```
24 24
 
25
-## 链接
25
+## 閾炬帴
26 26
 
27
-- [目录](directory.md)
28
-- 上一节:[接口是什么](11.1.md)
29
-- 下一节:[如何检测和转换接口变量的类型:类型断言](11.3.md)
27
+- [鐩�綍](directory.md)
28
+- 涓婁竴鑺傦細[鎺ュ彛鏄�粈涔圿(11.1.md)
29
+- 涓嬩竴鑺傦細[濡備綍妫€娴嬪拰杞�崲鎺ュ彛鍙橀噺鐨勭被鍨嬶細绫诲瀷鏂�█](11.3.md)

+ 17 - 17
eBook/11.3.md

@@ -1,14 +1,14 @@
1
-# 11.3 类型断言:如何检测和转换接口变量的类型
1
+# 11.3 类型断言:如何检测和转换接口变量的类型
2 2
 
3
-一个接口类型的变量 `varI` 中可以包含任何类型的值,必须有一种方式来检测它的 **动态** 类型,即运行时在变量中存储的值的实际类型。在执行过程中动态类型可能会有所不同,但是它总是可以分配给接口变量本身的类型。通常我们可以使用 **类型断言** 来测试在某个时刻 `varI` 是否包含类型 `T` 的值:
3
+一个接口类型的变量 `varI` 中可以包含任何类型的值,必须有一种方式来检测它的 **动态** 类型,即运行时在变量中存储的值的实际类型。在执行过程中动态类型可能会有所不同,但是它总是可以分配给接口变量本身的类型。通常我们可以使用 **类型断言** 来测试在某个时刻 `varI` 是否包含类型 `T` 的值:
4 4
 
5 5
 ```go
6 6
     v := varI.(T)       // unchecked type assertion
7 7
 ```
8 8
 
9
-**varI必须是一个接口变量**,否则编译器会报错:`invalid type assertion: varI.(T) (non-interface type (type of varI) on left)` 。
9
+**varI必须是一个接口变量**,否则编译器会报错:`invalid type assertion: varI.(T) (non-interface type (type of varI) on left)` 。
10 10
 
11
-类型断言可能是无效的,虽然编译器会尽力检查转换是否有效,但是它不可能预见所有的可能性。如果转换在程序运行时失败会导致错误发生。更安全的方式是使用以下形式来进行类型断言:
11
+类型断言可能是无效的,虽然编译器会尽力检查转换是否有效,但是它不可能预见所有的可能性。如果转换在程序运行时失败会导致错误发生。更安全的方式是使用以下形式来进行类型断言:
12 12
 
13 13
 ```go
14 14
 if v, ok := varI.(T); ok {  // checked type assertion
@@ -18,11 +18,11 @@ if v, ok := varI.(T); ok {  // checked type assertion
18 18
 // varI is not of type T
19 19
 ```
20 20
 
21
-如果转换合法,`v` 是 `varI` 转换到类型 `T`的值,`ok` 会是 `true`;否则 `v` 是类型 `T` 的零值,`ok` 是 `false`,也没有运行时错误发生。
21
+如果转换合法,`v` 是 `varI` 转换到类型 `T`的值,`ok` 会是 `true`;否则 `v` 是类型 `T` 的零值,`ok` 是 `false`,也没有运行时错误发生。
22 22
 
23
-**应该总是使用上面的方式来进行类型断言**。
23
+**应该总是使用上面的方式来进行类型断言**。
24 24
 
25
-多数情况下,我们可能只是想在 `if` 中测试一下 `ok` 的值,此时使用以下的方法会是最方便的:
25
+多数情况下,我们可能只是想在 `if` 中测试一下 `ok` 的值,此时使用以下的方法会是最方便的:
26 26
 
27 27
 ```go
28 28
 if _, ok := varI.(T); ok {
@@ -30,9 +30,9 @@ if _, ok := varI.(T); ok {
30 30
 }
31 31
 ```
32 32
 
33
-TODO ??:In this form shadowing the variable varI by giving varI and v the same name is sometimes done.
33
+TODO ??锛欼n this form shadowing the variable varI by giving varI and v the same name is sometimes done.
34 34
 
35
-示例 11.4 type_interfaces.go
35
+绀轰緥 11.4 type_interfaces.go
36 36
 
37 37
 ```go
38 38
 package main
@@ -80,19 +80,19 @@ func (ci *Circle) Area() float32 {
80 80
 }
81 81
 ```
82 82
 
83
-输出:
83
+输出:
84 84
 
85 85
     The type of areaIntf is: *main.Square
86 86
     areaIntf does not contain a variable of type Circle
87 87
 
88
-程序行中定义了一个新类型 `Circle`,它也实现了 `Shaper` 接口。 `t, ok := areaIntf.(*Square); ok ` 测试 `areaIntf` 里是否一个包含 'Square' 类型的变量,结果是确定的;然后我们测试它是否包含一个 'Circle' 类型的变量,结果是否定的。
88
+程序行中定义了一个新类型 `Circle`,它也实现了 `Shaper` 接口。 `t, ok := areaIntf.(*Square); ok ` 测试 `areaIntf` 里是否一个包含 'Square' 类型的变量,结果是确定的;然后我们测试它是否包含一个 'Circle' 类型的变量,结果是否定的。
89 89
 
90
-**备注**
90
+**澶囨敞**
91 91
 
92
-如果忽略 `areaIntf.(*Square)` 中的 `*` 号,会导致编译错误:`impossible type assertion: Square does not implement Shaper (Area method has pointer receiver)`。
92
+如果忽略 `areaIntf.(*Square)` 中的 `*` 号,会导致编译错误:`impossible type assertion: Square does not implement Shaper (Area method has pointer receiver)`。
93 93
 
94
-## 链接
94
+## 閾炬帴
95 95
 
96
-- [目录](directory.md)
97
-- 上一节:[接口嵌套接口](11.2.md)
98
-- 下一节:[类型判断:type-switch](11.4.md)
96
+- [鐩�綍](directory.md)
97
+- 涓婁竴鑺傦細[鎺ュ彛宓屽�鎺ュ彛](11.2.md)
98
+- 涓嬩竴鑺傦細[绫诲瀷鍒ゆ柇锛歵ype-switch](11.4.md)

+ 16 - 16
eBook/11.4.md

@@ -1,6 +1,6 @@
1
-# 11.4 类型判断:type-switch
1
+# 11.4 类型判断:type-switch
2 2
 
3
-接口变量的类型也可以使用一种特殊形式的 `swtich` 来检测:**type-swtich** (下面是 示例 11.4 的第二部分):
3
+接口变量的类型也可以使用一种特殊形式的 `swtich` 来检测:**type-swtich** (下面是 示例 11.4 的第二部分):
4 4
 
5 5
 ```go
6 6
 	switch t := areaIntf.(type) {
@@ -15,15 +15,15 @@
15 15
 	}
16 16
 ```
17 17
 
18
-输出:
18
+输出:
19 19
 
20 20
     Type Square *main.Square with value &{5}
21 21
 
22
-变量 `t` 得到了 `areaIntf` 的值和类型, 所有 `case` 语句中列举的类型(`nil` 除外)都必须实现对应的接口(在上例中即 `Shaper`),如果被检测类型没有在 `case` 语句列举的类型中,就会执行`default` 语句。
22
+变量 `t` 得到了 `areaIntf` 的值和类型, 所有 `case` 语句中列举的类型(`nil` 除外)都必须实现对应的接口(在上例中即 `Shaper`),如果被检测类型没有在 `case` 语句列举的类型中,就会执行`default` 语句。
23 23
 
24
-可以用 `type-switch` 进行运行时类型分析,但是在 `type-switch` 不允许有 `fallthrough` 。
24
+可以用 `type-switch` 进行运行时类型分析,但是在 `type-switch` 不允许有 `fallthrough` 。
25 25
 
26
-如果仅仅是测试变量的类型,不用它的值,那么就可以不需要赋值语句,比如:
26
+如果仅仅是测试变量的类型,不用它的值,那么就可以不需要赋值语句,比如:
27 27
 
28 28
 ```go
29 29
 	switch areaIntf.(type) {
@@ -37,7 +37,7 @@
37 37
 	}
38 38
 ```
39 39
 
40
-下面的代码片段展示了一个类型分类函数,它有一个可变长度参数,可以是任意类型的数组,它会根据数组元素的实际类型执行不同的动作:
40
+涓嬮潰鐨勪唬鐮佺墖娈靛睍绀轰簡涓€涓�被鍨嬪垎绫诲嚱鏁帮紝瀹冩湁涓€涓�彲鍙橀暱搴﹀弬鏁帮紝鍙�互鏄�换鎰忕被鍨嬬殑鏁扮粍锛屽畠浼氭牴鎹�暟缁勫厓绱犵殑瀹為檯绫诲瀷鎵ц�涓嶅悓鐨勫姩浣滐細
41 41
 
42 42
 ```go
43 43
 
@@ -61,18 +61,18 @@ func classifier(items ...interface{}) {
61 61
 }
62 62
 ```
63 63
 
64
-可以这样调用此方法:`classifier(13, -14.3, "BELGIUM", complex(1, 2), nil, false)` 。
64
+可以这样调用此方法:`classifier(13, -14.3, "BELGIUM", complex(1, 2), nil, false)` 。
65 65
 
66
-在处理来自于外部的、类型未知的数据时,比如解析诸如 JSON 或 XML 编码的数据,类型测试和转换会非常有用。
66
+在处理来自于外部的、类型未知的数据时,比如解析诸如 JSON 或 XML 编码的数据,类型测试和转换会非常有用。
67 67
 
68
-在 示例12.17(xml.go) 中解析 XML 文档是,我们就会用到 `type-switch` 。
68
+在 示例12.17(xml.go) 中解析 XML 文档是,我们就会用到 `type-switch` 。
69 69
 
70
-**练习 11.4** simple_interface2.go:
70
+**练习 11.4** simple_interface2.go:
71 71
 
72
-接着 练习11.1 中的内容,创建第二个类型 `RSimple`,它也实现了接口 `Simpler`,写一个函数 `fi`,它可以区分 `Simple` 和 `RSimple` 类型的变量。
72
+接着 练习11.1 中的内容,创建第二个类型 `RSimple`,它也实现了接口 `Simpler`,写一个函数 `fi`,它可以区分 `Simple` 和 `RSimple` 类型的变量。
73 73
 
74
-## 链接
74
+## 閾炬帴
75 75
 
76
-- [目录](directory.md)
77
-- 上一节:[类型断言:如何检测和转换接口变量的类型](11.3.md)
78
-- 下一节:[测试一个值是否实现了某个接口](11.5.md)
76
+- [鐩�綍](directory.md)
77
+- 涓婁竴鑺傦細[绫诲瀷鏂�█锛氬�浣曟�娴嬪拰杞�崲鎺ュ彛鍙橀噺鐨勭被鍨媇(11.3.md)
78
+- 涓嬩竴鑺傦細[娴嬭瘯涓€涓�€兼槸鍚﹀疄鐜颁簡鏌愪釜鎺ュ彛](11.5.md)

+ 12 - 12
eBook/11.5.md

@@ -1,6 +1,6 @@
1
-# 11.5 测试一个值是否实现了某个接口
1
+# 11.5 测试一个值是否实现了某个接口
2 2
 
3
-这是 11.3 类型断言中的一个特例:假定 `v` 是一个值,然后我们想测试它是否实现了 `Stringer` 接口,可以这样做:
3
+这是 11.3 类型断言中的一个特例:假定 `v` 是一个值,然后我们想测试它是否实现了 `Stringer` 接口,可以这样做:
4 4
 
5 5
 ```go
6 6
 type Stringer interface {
@@ -12,20 +12,20 @@ if sv, ok := v.(Stringer); ok {
12 12
 }
13 13
 ```
14 14
 
15
-`Print` 函数就是如此检测类型是否可以打印自身的。
15
+`Print` 函数就是如此检测类型是否可以打印自身的。
16 16
 
17
-接口是一种契约,实现类型必须满足它,它描述了类型的行为,规定类型可以做什么。接口彻底将类型能做什么,以及如何做分离开来,使得相同接口的变量在不同的时刻表现出不同的行为,这就是多态的本质。
17
+接口是一种契约,实现类型必须满足它,它描述了类型的行为,规定类型可以做什么。接口彻底将类型能做什么,以及如何做分离开来,使得相同接口的变量在不同的时刻表现出不同的行为,这就是多态的本质。
18 18
 
19
-编写参数是接口变量的函数,这使得它们更具有一般性。
19
+编写参数是接口变量的函数,这使得它们更具有一般性。
20 20
 
21
-**使用接口使代码更具有普适性。**
21
+**使用接口使代码更具有普适性。**
22 22
 
23
-标准库里到处都使用了这个原则,如果对接口概念没有良好的把握,是不可能理解它是如何构建的。
23
+标准库里到处都使用了这个原则,如果对接口概念没有良好的把握,是不可能理解它是如何构建的。
24 24
 
25
-在接下来的章节中,我们会讨论两个重要的例子,试着去深入理解它们,这样你就可以更好的应用上面的原则。
25
+在接下来的章节中,我们会讨论两个重要的例子,试着去深入理解它们,这样你就可以更好的应用上面的原则。
26 26
 
27
-## 链接
27
+## 閾炬帴
28 28
 
29
-- [目录](directory.md)
30
-- 上一节:[类型判断:type-switch](11.4.md)
31
-- 下一节:[使用方法集与接口](11.6.md)
29
+- [鐩�綍](directory.md)
30
+- 涓婁竴鑺傦細[绫诲瀷鍒ゆ柇锛歵ype-switch](11.4.md)
31
+- 涓嬩竴鑺傦細[浣跨敤鏂规硶闆嗕笌鎺ュ彛](11.6.md)

+ 22 - 22
eBook/11.6.md

@@ -1,8 +1,8 @@
1
-# 11.6 使用方法集与接口
1
+# 11.6 使用方法集与接口
2 2
 
3
-在 10.6.3 及例子 methodset1.go 中我们看到,作用于变量上的方法实际上是不区分变量到底是指针还是值的。当碰到接口类型值时,这会变得有点复杂,原因是接口变量中存储的具体值是不可寻址的,幸运的是,如果使用不当编译器会给出错误。考虑下面的程序:
3
+在 10.6.3 及例子 methodset1.go 中我们看到,作用于变量上的方法实际上是不区分变量到底是指针还是值的。当碰到接口类型值时,这会变得有点复杂,原因是接口变量中存储的具体值是不可寻址的,幸运的是,如果使用不当编译器会给出错误。考虑下面的程序:
4 4
 
5
-示例 11.5 methodset2.go:
5
+绀轰緥 11.5 methodset2.go:
6 6
 
7 7
 ```go
8 8
 package main
@@ -60,34 +60,34 @@ func main() {
60 60
 }
61 61
 ```
62 62
 
63
-**讨论**
63
+**璁ㄨ�**
64 64
 
65
-在 `lst` 上调用 `CountInto` 时会导致一个编译器错误,因为 `CountInto` 需要一个 `Appender`,而它的方法 `Append` 只定义在指针上。 在 `lst` 上调用 `LongEnough` 是可以的因为 'Len' 定义在值上。
65
+在 `lst` 上调用 `CountInto` 时会导致一个编译器错误,因为 `CountInto` 需要一个 `Appender`,而它的方法 `Append` 只定义在指针上。 在 `lst` 上调用 `LongEnough` 是可以的因为 'Len' 定义在值上。
66 66
 
67
-在 `plst` 上调用 `CountInto` 是可以的,因为 `CountInto` 需要一个 `Appender`,并且它的方法 `Append` 定义在指针上。 在 `plst` 上调用 `LongEnough` 也是可以的,因为指针会被自动解引用。
67
+在 `plst` 上调用 `CountInto` 是可以的,因为 `CountInto` 需要一个 `Appender`,并且它的方法 `Append` 定义在指针上。 在 `plst` 上调用 `LongEnough` 也是可以的,因为指针会被自动解引用。
68 68
 
69
-**总结**
69
+**鎬荤粨**
70 70
 
71
-在接口上调用方法时,必须有和方法定义时相同的接收者类型或者是可以从具体类型 `P` 直接可以辨识的:
71
+在接口上调用方法时,必须有和方法定义时相同的接收者类型或者是可以从具体类型 `P` 直接可以辨识的:
72 72
 
73
-- 指针方法可以通过指针调用
74
-- 值方法可以通过值调用
75
-- 接收者是值的方法可以通过指针调用,因为指针会首先被解引用
76
-- 接收者是指针的方法不可以通过值调用,因为存储在接口中的值没有地址
73
+- 鎸囬拡鏂规硶鍙�互閫氳繃鎸囬拡璋冪敤
74
+- 值方法可以通过值调用
75
+- 鎺ユ敹鑰呮槸鍊肩殑鏂规硶鍙�互閫氳繃鎸囬拡璋冪敤锛屽洜涓烘寚閽堜細棣栧厛琚�В寮曠敤
76
+- 鎺ユ敹鑰呮槸鎸囬拡鐨勬柟娉曚笉鍙�互閫氳繃鍊艰皟鐢�紝鍥犱负瀛樺偍鍦ㄦ帴鍙d腑鐨勫€兼病鏈夊湴鍧€
77 77
 
78
-将一个值赋值给一个接口赋值时,编译器会确保所有可能的接口方法都可以在此值上被调用,因此不正确的赋值在编译期就会失败。
78
+将一个值赋值给一个接口赋值时,编译器会确保所有可能的接口方法都可以在此值上被调用,因此不正确的赋值在编译期就会失败。
79 79
 
80 80
 
81
-**译注**
81
+**璇戞敞**
82 82
 
83
-Go语言规范定义了接口方法集的调用规则:
83
+Go璇�█瑙勮寖瀹氫箟浜嗘帴鍙f柟娉曢泦鐨勮皟鐢ㄨ�鍒欙細
84 84
 
85
-- 类型 *T 的可调用方法集包含接受者为 *T 或 T 的所有方法集
86
-- 类型 T 的可调用方法集包含接受者为 T 的所有方法
87
-- 类型 T 的可调用方法集不包含接受者为 *T 的方法
85
+- 类型 *T 的可调用方法集包含接受者为 *T 或 T 的所有方法集
86
+- 类型 T 的可调用方法集包含接受者为 T 的所有方法
87
+- 类型 T 的可调用方法集不包含接受者为 *T 的方法
88 88
 
89
-## 链接
89
+## 閾炬帴
90 90
 
91
-- [目录](directory.md)
92
-- 上一节:[测试一个值是否实现了某个接口](11.5.md)
93
-- 下一节:[第一个例子:使用Sorter接口排序](11.7.md)
91
+- [鐩�綍](directory.md)
92
+- 涓婁竴鑺傦細[娴嬭瘯涓€涓�€兼槸鍚﹀疄鐜颁簡鏌愪釜鎺ュ彛](11.5.md)
93
+- 涓嬩竴鑺傦細[绗�竴涓�緥瀛愶細浣跨敤Sorter鎺ュ彛鎺掑簭](11.7.md)

+ 34 - 34
eBook/11.7.md

@@ -1,9 +1,9 @@
1
-# 11.7 第一个例子:使用Sorter接口排序
1
+# 11.7 第一个例子:使用Sorter接口排序
2 2
 
3
-一个很好的例子是来自标准库的 `sort` 包,要对一组数字或字符串排序,只需要实现三个方法:反映元素个数的 `Len()`方法、比较第 `i` 和 `j` 个元素的 `Less(i, j)` 方法以及交换第 `i` 和 `j` 个元素的 `Swap(i, j)` 方法。
3
+一个很好的例子是来自标准库的 `sort` 包,要对一组数字或字符串排序,只需要实现三个方法:反映元素个数的 `Len()`方法、比较第 `i` 和 `j` 个元素的 `Less(i, j)` 方法以及交换第 `i` 和 `j` 个元素的 `Swap(i, j)` 方法。
4 4
 
5 5
 
6
-排序函数的算法只会使用到这三个方法(可以使用任何排序算法来实现,此处我们使用冒泡排序):
6
+鎺掑簭鍑芥暟鐨勭畻娉曞彧浼氫娇鐢ㄥ埌杩欎笁涓�柟娉曪紙鍙�互浣跨敤浠讳綍鎺掑簭绠楁硶鏉ュ疄鐜帮紝姝ゅ�鎴戜滑浣跨敤鍐掓场鎺掑簭锛夛細
7 7
 
8 8
 ```go
9 9
 func Sort(data Sorter) {
@@ -17,7 +17,7 @@ func Sort(data Sorter) {
17 17
 }
18 18
 ```
19 19
 
20
-`Sort` 函数接收一个接口类型参数: `Sorter` ,它声明了这些方法:
20
+`Sort` 鍑芥暟鎺ユ敹涓€涓�帴鍙g被鍨嬪弬鏁帮細 `Sorter` 锛屽畠澹版槑浜嗚繖浜涙柟娉曪細
21 21
 
22 22
 ```go
23 23
 type Sorter interface {
@@ -27,9 +27,9 @@ type Sorter interface {
27 27
 }
28 28
 ```
29 29
 
30
-参数中的 `int` 不是说要排序的对象一定要是一组 `int`,`i` 和 `j` 表示元素的整型索引,长度也是整型的。
30
+参数中的 `int` 不是说要排序的对象一定要是一组 `int`,`i` 和 `j` 表示元素的整型索引,长度也是整型的。
31 31
 
32
-现在如果我们想对一个 `int` 数组进行排序,所有必须做的事情就是:为数组定一个类型并在它上面实现 `Sorter` 接口的方法:
32
+现在如果我们想对一个 `int` 数组进行排序,所有必须做的事情就是:为数组定一个类型并在它上面实现 `Sorter` 接口的方法:
33 33
 
34 34
 ```go
35 35
 type IntArray []int
@@ -38,7 +38,7 @@ func (p IntArray) Less(i, j int) bool { return p[i] < p[j] }
38 38
 func (p IntArray) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
39 39
 ```
40 40
 
41
-下面是调用排序函数的一个具体例子:
41
+涓嬮潰鏄�皟鐢ㄦ帓搴忓嚱鏁扮殑涓€涓�叿浣撲緥瀛愶細
42 42
 
43 43
 ```go
44 44
 data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586}
@@ -46,11 +46,11 @@ a := sort.IntArray(data) //conversion to type IntArray from package sort
46 46
 sort.Sort(a)
47 47
 ```
48 48
 
49
-完整的、可运行的代码可以在 `sort.go` 和 `sortmain.go` 里找到。
49
+完整的、可运行的代码可以在 `sort.go` 和 `sortmain.go` 里找到。
50 50
 
51
-同样的原理,排序函数可以用于一个浮点型数组,一个字符串数组,或者一个表示每周各天的结构体 `dayArray`.
51
+同样的原理,排序函数可以用于一个浮点型数组,一个字符串数组,或者一个表示每周各天的结构体 `dayArray`.
52 52
 
53
-示例 11.6 sort.go:
53
+示例 11.6 sort.go:
54 54
 
55 55
 ```go
56 56
 package sort
@@ -102,7 +102,7 @@ func IntsAreSorted(a []int) bool       { return IsSorted(IntArray(a)) }
102 102
 func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)) }
103 103
 ```
104 104
 
105
-示例 11.7 sortmain.go:
105
+示例 11.7 sortmain.go:
106 106
 
107 107
 ```go
108 108
 package main
@@ -173,17 +173,17 @@ func main() {
173 173
 }
174 174
 ```
175 175
 
176
-输出:
176
+输出:
177 177
 
178 178
     The sorted array is: [-5467984 -784 0 0 42 59 74 238 905 959 7586 7586 9845]
179 179
     The sorted array is: [ friday monday saturday sunday thursday tuesday wednesday]
180 180
     Sunday Monday Tuesday Wednesday Thursday Friday Saturday 
181 181
 
182
-**备注**:
182
+**备注**:
183 183
 
184
-`panic("fail")` 用于停止处于在非正常情况下的程序(详细请参考 第13章),当然也可以先打印一条信息,然后调用 `os.Exit(1)` 来停止程序。
184
+`panic("fail")` 用于停止处于在非正常情况下的程序(详细请参考 第13章),当然也可以先打印一条信息,然后调用 `os.Exit(1)` 来停止程序。
185 185
 
186
-上面的例子帮助我们进一步了解了接口的意义和使用方式。对于基本类型的排序,标准库已经提供了相关的排序函数,所以不需要我们再重复造轮子了。对于一般性的排序,`sort` 包定义了一个接口:
186
+涓婇潰鐨勪緥瀛愬府鍔╂垜浠�繘涓€姝ヤ簡瑙d簡鎺ュ彛鐨勬剰涔夊拰浣跨敤鏂瑰紡銆傚�浜庡熀鏈�被鍨嬬殑鎺掑簭锛屾爣鍑嗗簱宸茬粡鎻愪緵浜嗙浉鍏崇殑鎺掑簭鍑芥暟锛屾墍浠ヤ笉闇€瑕佹垜浠�啀閲嶅�閫犺疆瀛愪簡銆傚�浜庝竴鑸�€х殑鎺掑簭锛宍sort` 鍖呭畾涔変簡涓€涓�帴鍙o細
187 187
 
188 188
 ```go
189 189
 type Interface interface {
@@ -193,36 +193,36 @@ type Interface interface {
193 193
 }
194 194
 ```
195 195
 
196
-这个接口总结了需要用于排序的抽象方法,函数 `Sort(data Interface)` 用来对此类对象进行排序,可以用它们来实现对其他数据(非基本类型)进行排序。在上面的例子中,我们也是这么做的,不仅可以对 `int` 和 `string` 序列进行排序,也可以对用户自定义类型 `dayArray` 进行排序。
196
+这个接口总结了需要用于排序的抽象方法,函数 `Sort(data Interface)` 用来对此类对象进行排序,可以用它们来实现对其他数据(非基本类型)进行排序。在上面的例子中,我们也是这么做的,不仅可以对 `int` 和 `string` 序列进行排序,也可以对用户自定义类型 `dayArray` 进行排序。
197 197
 
198
-**练习 11.5** interfaces_ext.go:
198
+**练习 11.5** interfaces_ext.go:
199 199
 
200
-a). 继续扩展程序,定义类型 `Triangle`,让它实现 `AreaInterface` 接口。通过计算一个特定三角形的面积来进行测试(三角形面积=0.5 * (底 * 高))
200
+a). 继续扩展程序,定义类型 `Triangle`,让它实现 `AreaInterface` 接口。通过计算一个特定三角形的面积来进行测试(三角形面积=0.5 * (底 * 高))
201 201
 
202
-b). 定义一个新接口 `PeriInterface`,它有一个 `Perimeter` 接口。让 `Square` 实现这个接口,并通过一个 `Square` 示例来测试它。
202
+b). 定义一个新接口 `PeriInterface`,它有一个 `Perimeter` 接口。让 `Square` 实现这个接口,并通过一个 `Square` 示例来测试它。
203 203
 
204
-**练习 11.6** point_interfaces.go:
204
+**练习 11.6** point_interfaces.go:
205 205
 
206
-继续 10.3 中的练习 point_methods.go,定义接口 `Magnitude`,它有一个方法 `Abs()`。让 `Point`、`Point3` 及`Polar` 实现此接口。通过接口类型变量使用方法做point.go中同样的事情。
206
+继续 10.3 中的练习 point_methods.go,定义接口 `Magnitude`,它有一个方法 `Abs()`。让 `Point`、`Point3` 及`Polar` 实现此接口。通过接口类型变量使用方法做point.go中同样的事情。
207 207
 
208
-**练习 11.7** float_sort.go / float_sortmain.go:
208
+**练习 11.7** float_sort.go / float_sortmain.go:
209 209
 
210
-类似11.7和示例11.3/4,定义一个包 `float64`,并在包里定义类型 `Float64Array`,然后让它实现 `Sorter` 接口用来对 `float64` 数组进行排序。
210
+类似11.7和示例11.3/4,定义一个包 `float64`,并在包里定义类型 `Float64Array`,然后让它实现 `Sorter` 接口用来对 `float64` 数组进行排序。
211 211
 
212
-另外提供如下方法:
212
+另外提供如下方法:
213 213
 
214
-- `NewFloat64Array()`:创建一个包含25个元素的数组变量(参考10.2)
215
-- `List()`:返回数组格式化后的字符串,并在 `String()` 方法中调用它,这样就不用显式地调用 `List()` 来打印数组(参考10.7)
216
-- `Fill()`:创建一个包含10个随机浮点数的数组(参考4.5.2.6)
214
+- `NewFloat64Array()`:创建一个包含25个元素的数组变量(参考10.2)
215
+- `List()`:返回数组格式化后的字符串,并在 `String()` 方法中调用它,这样就不用显式地调用 `List()` 来打印数组(参考10.7)
216
+- `Fill()`:创建一个包含10个随机浮点数的数组(参考4.5.2.6)
217 217
 
218
-在主程序中新建一个此类型的变量,然后对它排序并进行测试。
218
+在主程序中新建一个此类型的变量,然后对它排序并进行测试。
219 219
 
220
-**练习 11.8** sort.go/sort_persons.go:
220
+**练习 11.8** sort.go/sort_persons.go:
221 221
 
222
-定义一个结构体 `Person`,它有两个字段:`firstName` 和 `lastName`,为 `[]Person` 定义类型 `Persons` 。让 `Persons` 实现 `Sorter` 接口并进行测试。
222
+定义一个结构体 `Person`,它有两个字段:`firstName` 和 `lastName`,为 `[]Person` 定义类型 `Persons` 。让 `Persons` 实现 `Sorter` 接口并进行测试。
223 223
 
224
-## 链接
224
+## 閾炬帴
225 225
 
226
-- [目录](directory.md)
227
-- 上一节:[使用方法集与接口](11.6.md)
228
-- 下一节:[第二个例子:读和写](11.8.md)
226
+- [鐩�綍](directory.md)
227
+- 涓婁竴鑺傦細[浣跨敤鏂规硶闆嗕笌鎺ュ彛](11.6.md)
228
+- 涓嬩竴鑺傦細[绗�簩涓�緥瀛愶細璇诲拰鍐橾(11.8.md)

File diff suppressed because it is too large
+ 11 - 11
eBook/11.8.md


+ 41 - 41
eBook/11.9.md

@@ -1,20 +1,20 @@
1
-# 11.9 ソユスモソレ
1
+�ソ# 11.9 遨コ謗・蜿」
2 2
 
3
-## 11.9.1 ����
3
+## 11.9.1 讎ょソオ
4 4
 
5
-**ソユスモソレサ�゚ラ隯。スモソレ**イサー�ャネホコホキスキィ」ャヒ�ヤハオマヨイサラ�ホコホメェヌ�コ
5
+**空接口或者最小接口**不包含任何方法,它对实现不做任何要求:
6 6
 
7 7
 ```go
8 8
 type Any interface {}
9 9
 ```
10 10
 
11
-�κ��������Ͷ�ʵ���˿սӿڣ����������� `Java/C#` �� `Object` �������ͣ���`any` �� `Any` �ǿսӿ�һ���ܺõı�������д��
11
+任何其他类型都实现了空接口(它不仅仅像 `Java/C#` 中 `Object` 引用类型),`any` 或 `Any` 是空接口一个很好的别名或缩写。
12 12
 
13
-�սӿ����� `Java/C#` ���������Ļ��ࣺ `Object` �࣬���ߵ�Ŀ��Ҳ��������
13
+空接口类似 `Java/C#` 中所有类的基类: `Object` 类,二者的目标也很相近。
14 14
 
15
-ソノメヤク�サク�ユスモソレタ獎ヘオトア菽ソ `var val interface {}` クウネホコホタ獎ヘオトヨオ。」
15
+可以给一个空接口类型的变量 `var val interface {}` 赋任何类型的值。
16 16
 
17
-ʾ�� 11.8 empty_interface.go��
17
+示例 11.8 empty_interface.go:
18 18
 
19 19
 ```go
20 20
 package main
@@ -56,16 +56,16 @@ func main() {
56 56
 }
57 57
 ```
58 58
 
59
-ハ莎�コ
59
+输出:
60 60
 
61 61
     val has the value: 5
62 62
     val has the value: ABC
63 63
     val has the value: &{Rob Pike 55}
64 64
     Type pointer to Person *main.Person
65 65
 
66
-�������������У��ӿڱ��� `val` �����θ���һ�� `int`��`string` �� `Person` ʵ����ֵ��Ȼ��ʹ�� `type-swtich` ����������ʵ�����͡�ÿ�� `interface {}` �������ڴ���ռ�������ֳ���һ�������洢�����������ͣ���һ�������洢�����������ݻ���ָ�����ݵ�ָ�롣
66
+在上面的例子中,接口变量 `val` 被依次赋予一个 `int`,`string` 和 `Person` 实例的值,然后使用 `type-swtich` 来测试它的实际类型。每个 `interface {}` 变量在内存中占据两个字长:一个用来存储它包含的类型,另一个用来存储它包含的数据或者指向数据的指针。
67 67
 
68
-���� emptyint_switch.go ˵���˿սӿ��� `type-swtich` ������ `lambda` �������÷���
68
+例子 emptyint_switch.go 说明了空接口在 `type-swtich` 中联合 `lambda` 函数的用法:
69 69
 
70 70
 ```go
71 71
 package main
@@ -101,21 +101,21 @@ func main() {
101 101
 }
102 102
 ```
103 103
 
104
-ハ莎�コ
104
+输出:
105 105
 
106 106
     any hello is a special String!
107 107
 
108
-**チキマー 11.9** simple_interface3.go」コ
108
+**练习 11.9** simple_interface3.go:
109 109
 
110
-���� ��ϰ11.2������������һ�� `gI` �����������ٽ��� `Simpler` ���͵IJ��������ǽ���һ���սӿڲ�����Ȼ��ͨ�����Ͷ����жϲ����Ƿ��� `Simpler` ���͡������� `main` ʹ�� `gI` ȡ�� `fI` ��������������ȷ�����Ĵ����㹻��ȫ��
110
+继续 练习11.2,在它中添加一个 `gI` 函数,它不再接受 `Simpler` 类型的参数,而是接受一个空接口参数。然后通过类型断言判断参数是否是 `Simpler` 类型。最后在 `main` 使用 `gI` 取代 `fI` 函数并调用它。确保你的代码足够安全。
111 111
 
112
-## 11.9.2 ����ͨ�����ͻ�������ͬ���ͱ���������
112
+## 11.9.2 构建通用类型或包含不同类型变量的数组
113 113
 
114
-�� 7.6.6 �����ǿ������ܱ������������� `int` ���顢`float` �����Լ� `string` ���飬��ô�����������͵������أ��Dz������DZ������Լ�����ʵ�����ǣ�
114
+在 7.6.6 中我们看到了能被搜索和排序的 `int` 数组、`float` 数组以及 `string` 数组,那么对于其他类型的数组呢,是不是我们必须得自己编程实现它们?
115 115
 
116
-��������֪������ô���ˣ�����ͨ��ʹ�ÿսӿڡ������Ǹ��սӿڶ�һ���������� `Element`��`type Element interface{}`
116
+现在我们知道该怎么做了,就是通过使用空接口。让我们给空接口定一个别名类型 `Element`:`type Element interface{}`
117 117
 
118
-Ȼ������һ���������͵Ľṹ�� `Vector`��������һ�� `Element` ����Ԫ�ص���Ƭ��
118
+然后定义一个容器类型的结构体 `Vector`,它包含一个 `Element` 类型元素的切片:
119 119
 
120 120
 ```go
121 121
 type Vector struct {
@@ -123,7 +123,7 @@ type Vector struct {
123 123
 }
124 124
 ```
125 125
 
126
-`Vector` ���ܷ��κ����͵ı�������Ϊ�κ����Ͷ�ʵ���˿սӿڣ�ʵ���� `Vector` ���ŵ�ÿ��Ԫ�ؿ����Dz�ͬ���͵ı���������Ϊ������һ�� `At()` �������ڷ��ص� `i` ��Ԫ�أ�
126
+`Vector` 里能放任何类型的变量,因为任何类型都实现了空接口,实际上 `Vector` 里放的每个元素可以是不同类型的变量。我们为它定义一个 `At()` 方法用于返回第 `i` 个元素:
127 127
 
128 128
 ```go
129 129
 func (p *Vector) At(i int) Element {
@@ -131,7 +131,7 @@ func (p *Vector) At(i int) Element {
131 131
 }
132 132
 ```
133 133
 
134
-�ٶ�һ�� `Set()` �����������õ� `i` ��Ԫ�ص�ֵ��
134
+再定一个 `Set()` 方法用于设置第 `i` 个元素的值:
135 135
 
136 136
 ```go
137 137
 func (p *Vector) Set(i int, e Element) {
@@ -139,26 +139,26 @@ func (p *Vector) Set(i int, e Element) {
139 139
 }
140 140
 ```
141 141
 
142
-`Vector` ヨミエ豢「オトヒ�ミヤェヒリカシハヌ `Element` タ獎ヘ」ャメェオテオスヒ�ヌオトヤュハシタ獎ヘ」ィunboxing」コイ�茱ゥミ靨ェモテオスタ獎ヘカマムヤ。」TODO」コThe compiler rejects assertions guaranteed to fail」ャタ獎ヘカマムヤラワハヌヤレヤヒミミハアイナヨエミミ」ャメ�ヒヒ�盍揵昤ヒミミハアエ﨔�」
142
+`Vector` 中存储的所有元素都是 `Element` 类型,要得到它们的原始类型(unboxing:拆箱)需要用到类型断言。TODO:The compiler rejects assertions guaranteed to fail,类型断言总是在运行时才执行,因此它会产生运行时错误。
143 143
 
144
-**チキマー 11.10** min_interface.go / minmain.go」コ
144
+**练习 11.10** min_interface.go / minmain.go:
145 145
 
146
-����11.7�п����� `Sorter` �ӿڣ�����һ�� `Miner` �ӿڲ�ʵ��һЩ��Ҫ�IJ��������� `Min` ����һ�� `Miner` ���ͱ����ļ��ϣ�Ȼ�����㲢���ؼ�������С��Ԫ�ء�
146
+仿照11.7中开发的 `Sorter` 接口,创建一个 `Miner` 接口并实现一些必要的操作。函数 `Min` 接受一个 `Miner` 类型变量的集合,然后计算并返回集合中最小的元素。
147 147
 
148
-## 11.9.3 ����������Ƭ���սӿ���Ƭ
148
+## 11.9.3 螟榊宛謨ー謐ョ蛻�援閾ウ遨コ謗・蜿」蛻�援
149 149
 
150
-��������һ�� `myType` ���͵�������Ƭ�����뽫��Ƭ�е����ݸ��Ƶ�һ���սӿ���Ƭ�У����ƣ�
150
+假设你有一个 `myType` 类型的数据切片,你想将切片中的数据复制到一个空接口切片中,类似:
151 151
 
152 152
 ```go
153 153
 var dataSlice []myType = FuncReturnSlice()
154 154
 var interfaceSlice []interface{} = dataSlice
155 155
 ```
156 156
 
157
-ソノマァイサトワユ篥エラ�ャア默�アサ盖�惞コ`cannot use dataSlice (type []myType) as type []interface { } in assignment`
157
+蜿ッ諠應ク崎�霑吩ケ亥★�檎シ冶ッ第慮莨壼�髞呻シ啻cannot use dataSlice (type []myType) as type []interface { } in assignment`
158 158
 
159
-ヤュメ�ヌヒ�ヌチゥヤレトレエ贍ミオトイシセヨハヌイサメサム�ト」ィイホソシ[http://golang.org/doc/go_spec.html](http://golang.org/doc/go_spec.html)」ゥ。」
159
+原因是它们俩在内存中的布局是不一样的(参考[http://golang.org/doc/go_spec.html](http://golang.org/doc/go_spec.html))。
160 160
 
161
-アリミ�ケモテ `for-range` モ�菎エメサク�サク�ヤハスオリクエヨニ」コ
161
+必须使用 `for-range` 语句来一个一个显式地复制:
162 162
 
163 163
 ```go
164 164
 var dataSlice []myType = FuncReturnSlice()
@@ -168,11 +168,11 @@ for ix, d := range dataSlice {
168 168
 }
169 169
 ```
170 170
 
171
-## 11.9.4 ͨ�����͵Ľڵ����ݽṹ
171
+## 11.9.4 騾夂畑邀サ蝙狗噪闃らせ謨ー謐ョ扈捺桷
172 172
 
173
-��10.1�����������������б��������������ݽṹ�������ǵĶ�����ʹ����һ�ֽнڵ��ĵݹ��ṹ�����ͣ��ڵ�����һ��ij�����͵������ֶΡ����ڿ���ʹ�ÿսӿ���Ϊ�����ֶε����ͣ��������Ǿ���д��ͨ�õĴ��롣������ʵ��һ���������IJ��ִ��룺ͨ�ö��塢���ڴ����սڵ��� `NewNode` ���������������ݵ� `SetData` ����.
173
+在10.1中我们遇到了诸如列表和树这样的数据结构,在它们的定义中使用了一种叫节点的递归结构体类型,节点包含一个某种类型的数据字段。现在可以使用空接口作为数据字段的类型,这样我们就能写出通用的代码。下面是实现一个二叉树的部分代码:通用定义、用于创建空节点的 `NewNode` 方法,及设置数据的 `SetData` 方法.
174 174
 
175
-ʾ�� 11.10 node_structures.go:
175
+示例 11.10 node_structures.go:
176 176
 
177 177
 ```go
178 178
 package main
@@ -207,11 +207,11 @@ func main() {
207 207
 }
208 208
 ```
209 209
 
210
-## 11.9.5 スモソレオススモソレ
210
+## 11.9.5 謗・蜿」蛻ー謗・蜿」
211 211
 
212
-メサク�モソレオトヨオソノメヤクウヨオク�橫サク�モソレア菽ソ」ャヨサメェオライ翅獎ヘハオマヨチヒアリメェオトキスキィ。」ユ篋�ェササハヌヤレヤヒミミハアス�ミシ�魴ト」ャラェササハァーワサ盞シヨツメサク�ヒミミハアエ﨔�コユ簗ヌ 'Go' モ�ヤカッフャオトメサテ譽ャソノメヤトヌヒ�ヘ `Ruby` コヘ `Python` ユ簟ゥカッフャモ�ヤマ牾ネスマ。」
212
+一个接口的值可以赋值给另一个接口变量,只要底层类型实现了必要的方法。这个转换是在运行时进行检查的,转换失败会导致一个运行时错误:这是 'Go' 语言动态的一面,可以那它和 `Ruby` 和 `Python` 这些动态语言相比较。
213 213
 
214
-シルカィ」コ
214
+假定:
215 215
 
216 216
 ```go
217 217
 var ai AbsInterface // declares method Abs()
@@ -223,18 +223,18 @@ pp := new(Point) // say *Point implements Abs, Sqr
223 223
 var empty interface{}
224 224
 ```
225 225
 
226
-トヌテエマツテ豬トモ�莠ヘタ獎ヘカマムヤハヌコマキィオト」コ
226
+那么下面的语句和类型断言是合法的:
227 227
 
228 228
 ```go
229 229
 empty = pp                // everything satisfies empty
230 230
 ai = empty.(AbsInterface) // underlying value pp implements Abs()
231 231
 // (runtime failure otherwise)
232
-si = ai.(SqrInterface) // *Point has Sqr() even though AbsInterface doesn。ッt
232
+si = ai.(SqrInterface) // *Point has Sqr() even though AbsInterface doesn窶冲
233 233
 empty = si             // *Point implements empty set
234 234
 // Note: statically checkable so type assertion not necessary.
235 235
 ```
236 236
 
237
-�����Ǻ������õ�һ�����ӣ�
237
+下面是函数调用的一个例子:
238 238
 
239 239
 ```go
240 240
 type myPrintInterface interface {
@@ -246,10 +246,10 @@ func f3(x myInterface) {
246 246
 }
247 247
 ```
248 248
 
249
-`x` ת��Ϊ `myPrintInterface` ��������ȫ��̬�ģ�ֻҪ `x` �ĵײ����ͣ���̬���ͣ������� `print` �����������þͿ����������С�
249
+`x` 转换为 `myPrintInterface` 类型是完全动态的:只要 `x` 的底层类型(动态类型)定义了 `print` 方法这个调用就可以正常运行。
250 250
 
251
-## チエスモ
251
+## 體セ謗・
252 252
 
253
-- [トソツシ](directory.md)
254
-- ��һ�ڣ�[�ڶ������ӣ�����д](11.8.md)
255
-- マツメサスレ」コ[キエノ莢�(11.10.md)
253
+- [逶ョ蠖評(directory.md)
254
+- 上一节:[第二个例子:读和写](11.8.md)
255
+- 下一节:[反射包](11.10.md)