第7章,部分字词修订,语序调整。少量错误修订。

This commit is contained in:
zhliner
2017-08-24 22:29:24 +08:00
parent 9a9b9a0594
commit 17919273e1
14 changed files with 87 additions and 87 deletions

View File

@@ -24,7 +24,7 @@ rwc = w // compile error: io.Writer lacks Close method
因为ReadWriter和ReadWriteCloser包含所有Writer的方法所以任何实现了ReadWriter和ReadWriteCloser的类型必定也实现了Writer接口
在进一步学习前,必须先解释表示一个类型持有一个方法当中的细节。回想在6.2章中对于每一个命名过的具体类型T它一些方法的接收者是类型T本身然而另一些则是一个`*T`的指针。还记得在T类型的参数上调用一个`*T`的方法是合法的只要这个参数是一个变量编译器隐式的获取了它的地址。但这仅仅是一个语法糖T类型的值不拥有所有`*T`指针的方法,这样它就可能只实现更少的接口。
在进一步学习前,必须先解释一个类型持有一个方法的表示当中的细节。回想在6.2章中对于每一个命名过的具体类型T一些方法的接收者是类型T本身然而另一些则是一个`*T`的指针。还记得在T类型的参数上调用一个`*T`的方法是合法的只要这个参数是一个变量编译器隐式的获取了它的地址。但这仅仅是一个语法糖T类型的值不拥有所有`*T`指针的方法,这样它就可能只实现更少的接口。
举个例子可能会更清晰一点。在第6.5章中IntSet类型的String方法的接收者是一个指针类型所以我们不能在一个不能寻址的IntSet值上调用这个方法
@@ -50,7 +50,7 @@ var _ fmt.Stringer = s // compile error: IntSet lacks String method
12.8章包含了一个打印出任意值的所有方法的程序然后可以使用godoc -analysis=type tool(§10.7.4)展示每个类型的方法和具体类型和接口之间的关系
就像信封封装和隐藏信件来一样,接口类型封装和隐藏具体类型和它的值。即使具体类型有其它的方法也只有接口类型暴露出来的方法会被调用到:
就像信封封装和隐藏信件来一样,接口类型封装和隐藏具体类型和它的值。即使具体类型有其它的方法也只有接口类型暴露出来的方法会被调用到:
```go
os.Stdout.Write([]byte("hello")) // OK: *os.File has Write method
@@ -62,7 +62,7 @@ w.Write([]byte("hello")) // OK: io.Writer has Write method
w.Close() // compile error: io.Writer lacks Close method
```
一个有更多方法的接口类型比如io.ReadWriter和少一些方法的接口类型,例如io.Reader进行对比更多方法的接口类型会告诉我们更多关于它的值持有的信息并且对实现它的类型要求更加严格。那么关于interface{}类型,它没有任何方法,请讲出哪些具体的类型实现了它?
一个有更多方法的接口类型比如io.ReadWriter和少一些方法的接口类型例如io.Reader进行对比更多方法的接口类型会告诉我们更多关于它的值持有的信息并且对实现它的类型要求更加严格。那么关于interface{}类型,它没有任何方法,请讲出哪些具体的类型实现了它?
这看上去好像没有用但实际上interface{}被称为空接口类型是不可或缺的。因为空接口类型对实现它的类型没有要求,所以我们可以将任意一个值赋给空接口类型。
@@ -75,11 +75,11 @@ any = map[string]int{"one": 1}
any = new(bytes.Buffer)
```
尽管不是很明显,从本书最早的例子中我们就已经在使用空接口类型。它允许像fmt.Println或者5.7章中的errorf函数接受任何类型的参数。
尽管不是很明显从本书最早的例子中我们就已经在使用空接口类型。它允许像fmt.Println或者5.7章中的errorf函数接受任何类型的参数。
对于创建的一个interface{}值持有一个booleanfloatstringmappointer或者任意其它的类型我们当然不能直接对它持有的值做操作因为interface{}没有任何方法。我们会在7.10章中学到一种用类型断言来获取interface{}中值的方法。
因为接口实现只依赖于判断两个类型的方法,所以没有必要定义一个具体类型和它实现的接口之间的关系。也就是说,尝试文档化和断言这种关系几乎没有用,所以并没有通过程序强制定义。下面的定义在编译期断言一个`*bytes.Buffer`的值实现了io.Writer接口类型:
因为接口实现只依赖于判断两个类型的方法,所以没有必要定义一个具体类型和它实现的接口之间的关系。也就是说,尝试文档化和断言这种关系几乎没有用,所以并没有通过程序强制定义。下面的定义在编译期断言一个`*bytes.Buffer`的值实现了io.Writer接口类型:
```go
// *bytes.Buffer must satisfy io.Writer
@@ -139,7 +139,7 @@ type Video interface {
}
```
这些接口不止是一种有用的方式来分组相关的具体类型和表示他们之间的共同特。我们后面可能会发现其它的分组。举例如果我们发现我们需要以同样的方式处理Audio和Video我们可以定义一个Streamer接口来代表它们之间相同的部分而不必对已经存在的类型做改变。
这些接口不止是一种有用的方式来分组相关的具体类型和表示他们之间的共同特。我们后面可能会发现其它的分组。举例如果我们发现我们需要以同样的方式处理Audio和Video我们可以定义一个Streamer接口来代表它们之间相同的部分而不必对已经存在的类型做改变。
```go
type Streamer interface {