|
|
@@ -18,17 +18,17 @@ type Namer interface {
|
|
|
|
|
|
上面的 `Namer` 是一个 **接口类型**。
|
|
|
|
|
|
-(按照约定,只包含一个方法的)接口的名字由方法名加 `[e]r` 后缀组成,例如 `Printer`、`Reader`、`Writer`、`Logger`、`Converter`等等。还有一些不常用的方式(当后缀`er`不合适时),比如`Recoverable`,此时接口名以`able`结尾,或者以 `I` 开头(像 `.NET` 或 `Java` 中那样)。
|
|
|
+(按照约定,只包含一个方法的)接口的名字由方法名加 `[e]r` 后缀组成,例如 `Printer`、`Reader`、`Writer`、`Logger`、`Converter` 等等。还有一些不常用的方式(当后缀 `er` 不合适时),比如 `Recoverable`,此时接口名以 `able` 结尾,或者以 `I` 开头(像 `.NET` 或 `Java` 中那样)。
|
|
|
|
|
|
-Go 语言中的接口都很简短,通常它们会包含0个、最多3个方法。
|
|
|
+Go 语言中的接口都很简短,通常它们会包含 0 个、最多 3 个方法。
|
|
|
|
|
|
-不像大多数面向对象编程语言,在 Go 语言中接口可以有值,一个接口类型的变量或一个 **接口值** :`var ai Namer`,`ai`是一个多字(multiword)数据结构,它的值是 `nil`。它本质上是一个指针,虽然不完全是一回事。指向接口值的指针是非法的,它们不仅一点用也没有,还会导致代码错误。
|
|
|
+不像大多数面向对象编程语言,在 Go 语言中接口可以有值,一个接口类型的变量或一个 **接口值** :`var ai Namer`,`ai` 是一个多字(multiword)数据结构,它的值是 `nil`。它本质上是一个指针,虽然不完全是一回事。指向接口值的指针是非法的,它们不仅一点用也没有,还会导致代码错误。
|
|
|
|
|
|

|
|
|
|
|
|
此处的方法指针表是通过运行时反射能力构建的。
|
|
|
|
|
|
-类型(比如结构体)实现接口方法集中的方法,每一个方法的实现说明了此方法是如何作用于该类型的:**即实现接口**,同时方法集也构成了该类型的接口。实现了 `Namer` 接口类型的变量可以赋值给 `ai` (接收者值),此时方法表中的指针会指向被实现的接口方法。当然如果另一个类型(也实现了该接口)的变量被赋值给`ai`,这二者(译者注:指针和方法实现)也会随之改变。
|
|
|
+类型(比如结构体)实现接口方法集中的方法,每一个方法的实现说明了此方法是如何作用于该类型的:**即实现接口**,同时方法集也构成了该类型的接口。实现了 `Namer` 接口类型的变量可以赋值给 `ai` (接收者值),此时方法表中的指针会指向被实现的接口方法。当然如果另一个类型(也实现了该接口)的变量被赋值给 `ai`,这二者(译者注:指针和方法实现)也会随之改变。
|
|
|
|
|
|
**类型不需要显式声明它实现了某个接口:接口被隐式地实现。多个类型可以实现同一个接口**。
|
|
|
|
|
|
@@ -83,7 +83,7 @@ func main() {
|
|
|
|
|
|
上面的程序定义了一个结构体 `Square` 和一个接口 `Shaper`,接口有一个方法 `Area()`。
|
|
|
|
|
|
-在 `main()` 方法中创建了一个 `Square` 的实例。在主程序外边定义了一个接收者类型是 `Square`方法的 `Area()`,用来计算正方形的面积:结构体 `Square` 实现了接口 `Shaper` 。
|
|
|
+在 `main()` 方法中创建了一个 `Square` 的实例。在主程序外边定义了一个接收者类型是 `Square` 方法的 `Area()`,用来计算正方形的面积:结构体 `Square` 实现了接口 `Shaper` 。
|
|
|
|
|
|
所以可以将一个 `Square` 类型的变量赋值给一个接口类型的变量:`areaIntf = sq1` 。
|
|
|
|
|
|
@@ -154,7 +154,7 @@ func main() {
|
|
|
|
|
|
也许从现在开始你将看到通过接口如何产生 **更干净**、**更简单** 及 **更具有扩展性** 的代码。在 11.12.3 中将看到在开发中为类型添加新的接口是多么的容易。
|
|
|
|
|
|
-下面是一个更具体的例子:有两个类型 `stockPosition` 和 `car`,它们都有一个 `getValue()` 方法,我们可以定义一个具有此方法的接口 `valuable`。接着定义一个使用 `valuable`类型作为参数的函数 `showValue()`,所有实现了 `valuable` 接口的类型都可以用这个函数。
|
|
|
+下面是一个更具体的例子:有两个类型 `stockPosition` 和 `car`,它们都有一个 `getValue()` 方法,我们可以定义一个具有此方法的接口 `valuable`。接着定义一个使用 `valuable` 类型作为参数的函数 `showValue()`,所有实现了 `valuable` 接口的类型都可以用这个函数。
|
|
|
|
|
|
示例 11.3 valuable.go:
|
|
|
|
|
|
@@ -209,7 +209,7 @@ func main() {
|
|
|
|
|
|
**一个标准库的例子**
|
|
|
|
|
|
-`io`包里有一个接口类型 `Reader`:
|
|
|
+`io` 包里有一个接口类型 `Reader`:
|
|
|
|
|
|
```go
|
|
|
type Reader interface {
|
|
|
@@ -252,5 +252,5 @@ b) 使用一个抽象类型 `Shape`(没有字段) 实现同样的功能,
|
|
|
|
|
|
- [目录](directory.md)
|
|
|
- 上一节:[接口(Interfaces)与反射(reflection)](11.0.md)
|
|
|
-- 下一节:[接口嵌套接口](11.2.md)
|
|
|
-
|
|
|
+- 下一节:[接口嵌套接口](11.2.md)
|
|
|
+
|