1、方法
Go 没有类。然而,仍然可以在结构体类型上定义方法。
方法接收者 出现在 func 关键字和方法名之间的参数中。
2、方法(续)
你可以对包中的 任意 类型定义任意方法,而不仅仅是针对结构体。
但是,不能对来自其他包的类型或基础类型定义方法。
3、接收者为指针的方法
方法可以与命名类型或命名类型的指针关联。
刚刚看到的两个 Abs 方法。一个是在 *Vertex 指针类型上,而另一个在 MyFloat 值类型上。 有两个原因需要使用指针接收者。首先避免在每个方法调用中拷贝值(如果值类型是大的结构体的话会更有效率)。其次,方法可以修改接收者指向的值。
尝试修改 Abs 的定义,同时 Scale 方法使用 Vertex 代替 *Vertex 作为接收者。
当 v 是 Vertex 的时候 Scale 方法没有任何作用。`Scale` 修改 `v`。当 v 是一个值(非指针),方法看到的是 Vertex 的副本,并且无法修改原始值。
Abs 的工作方式是一样的。只不过,仅仅读取 `v`。所以读取的是原始值(通过指针)还是那个值的副本并没有关系。
4、接口
接口类型是由一组方法定义的集合。
接口类型的值可以存放实现这些方法的任何值。
注意: 列子代码的 22 行存在一个错误。 由于 Abs 只定义在 *Vertex(指针类型) 上, 所以 Vertex(值类型) 不满足 `Abser`。
5、隐式接口
类型通过实现那些方法来实现接口。 没有显式声明的必要;所以也就没有关键字“implements“。
隐式接口解藕了实现接口的包和定义接口的包:互不依赖。
因此,也就无需在每一个实现上增加新的接口名称,这样同时也鼓励了明确的接口定义。
包 io 定义了 Reader 和 `Writer`;其实不一定要这么做。
6、Stringers
一个普遍存在的接口是 fmt 包中定义的 Stringer。
type Stringer struct {
String() string
}
Stringer 是一个可以用字符串描述自己的类型。`fmt`包 (还有许多其他包)使用这个来进行输出。
7、错误
Go 程序使用 error 值来表示错误状态。
与 fmt.Stringer 类似,`error` 类型是一个内建接口:
type error interface {
Error() string
}
(与 fmt.Stringer 类似,`fmt` 包在输出时也会试图匹配 `error`。)
通常函数会返回一个 error 值,调用的它的代码应当判断这个错误是否等于 `nil`, 来进行错误处理。
i, err := strconv.Atoi("42")
if err != nil {
fmt.Printf("couldn't convert number: %v\n", err)
}
fmt.Println("Converted integer:", i)
error 为 nil 时表示成功;非 nil 的 error 表示错误。
8、Readers
io 包指定了 io.Reader 接口, 它表示从数据流结尾读取。
Go 标准库包含了这个接口的许多实现, 包括文件、网络连接、压缩、加密等等。
io.Reader 接口有一个 Read 方法:
func (T) Read(b []byte) (n int, err error)
Read 用数据填充指定的字节 slice,并且返回填充的字节数和错误信息。 在遇到数据流结尾时,返回 io.EOF 错误。
例子代码创建了一个 strings.Reader。 并且以每次 8 字节的速度读取它的输出。
9、Web 服务器
包 http 通过任何实现了 http.Handler 的值来响应 HTTP 请求:
package http
type Handler interface {
ServeHTTP(w ResponseWriter, r *Request)
}
在这个例子中,类型 Hello 实现了 `http.Handler`。
访问 http://localhost:4000/ 会看到来自程序的问候。
注意: 这个例子无法在基于 web 的指南用户界面运行。为了尝试编写 web 服务器,可能需要安装 Go。
10、图片
Package image 定义了 Image 接口:
package image
type Image interface {
ColorModel() color.Model
Bounds() Rectangle
At(x, y int) color.Color
}
*注意*:`Bounds` 方法的 Rectangle 返回值实际上是一个 image.Rectangle, 其定义在 image 包中。
color.Color 和 color.Model 也是接口,但是通常因为直接使用预定义的实现 image.RGBA 和 image.RGBAModel 而被忽视了。这些接口和类型由image/color 包定义。
有疑问加站长微信联系(非本文作者)