这是我参与「第五届青训营 」伴学笔记创作活动的第3天
今天短短两小时的内容, 我需要用两个星期的时间来治愈.
今天先补一下Go基础.
1. package io
在 io 包中最重要的两个接口: Reader
和 Writer
接口.
只要满足这两个接口, 他就可以使用IO包的功能
Reader 接口的方法集只包含一个 Read 方法,因此,所有实现了 Read 方法的类型都满足 io.Reader
接口.
func ReadFrom(reader io.Reader, num int) ([]byte, error) {
p := make([]byte, num)
n, err := reader.Read(p)
if n > 0 {
return p[:n], nil
}
return p, err
}
ReadFrom
函数将 io.Reader
作为参数,也就是说,ReadFrom
可以从任意的地方读取数据,只要来源实现了 io.Reader
接口。比如,我们可以从标准输入、文件、字符串等读取数据,示例代码如下:
// 从标准输入读取
data, err = ReadFrom(os.Stdin, 11)
// 从普通文件读取,其中 file 是 os.File 的实例
data, err = ReadFrom(file, 9)
// 从字符串读取
data, err = ReadFrom(strings.NewReader("from string"), 12)
一个小细节: io.EOF
变量的定义:var EOF = errors.New("EOF")
,是 error 类型。根据 reader 接口的说明,在 n > 0 且数据被读完了的情况下,返回的 error 有可能是 EOF 也有可能是 nil。
Writer接口的定义如下:
type Writer interface {
Write(p []byte) (n int, err error)
}
同样的, 所有实现了Write方法的类型都实现了 io.Writer
接口。
在 os
包中我们能看到这样的代码:
var (
Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
)
也就是说,Stdin/Stdout/Stderr 只是三个特殊的文件类型的标识(即都是 os.File 的实例),我们可以知道,os.File 同时实现了这两个接口。
虽然Go文档中还没有直接列出实现了某个接口的所有类型。不过我们可以通过godoc -analysis
来列出都有哪些类型实现了某个接口。