Go语言中Reader接口定义了一个Read操作,实现了Reader接口的都有Read这个函数,接口的定义如下:
type Reader interface {
Read(p []byte) (n int, err error)
}
在实际使用的时候可能会对一个参数和这两个返回值有疑惑,什么时候返回什么值什么的,特别是类似于网络IO这种下面利用官网的文档说明一下。
Reader is the interface that wraps the basic Read method.
Read reads up to len(p) bytes into p. It returns the number of bytes read (0 <= n <= len(p)) and any error encountered. Even if Read returns n < len(p), it may use all of p as scratch space during the call. If some data is available but not len(p) bytes, Read conventionally returns what is available instead of waiting for more.
When Read encounters an error or end-of-file condition after successfully reading n > 0 bytes, it returns the number of bytes read. It may return the (non-nil) error from the same call or return the error (and n == 0) from a subsequent call. An instance of this general case is that a Reader returning a non-zero number of bytes at the end of the input stream may return either err == EOF or err == nil. The next Read should return 0, EOF.
Callers should always process the n > 0 bytes returned before considering the error err. Doing so correctly handles I/O errors that happen after reading some bytes and also both of the allowed EOF behaviors.
Implementations of Read are discouraged from returning a zero byte count with a nil error, except when len(p) == 0. Callers should treat a return of 0 and nil as indicating that nothing happened; in particular it does not indicate EOF.
Implementations must not retain p.
什么意思呢,这里我大体总结一下有下面几个要点:
- 一次Read调用最多读取len(p)字节的数据到缓冲区p中
- n表示这一次实际读取到字节数,(0 <= n <= len(p))
- err 表示这次读取操作的报错(如果有的话,没有则是nil)
- 即使读取到的字节数n小于len(p),在函数调用过程中调用主体也可能使用全部的p的空间(不知道这个说明是想表达什么)
- 当read到数据的时候,即使不够len(p)(此时IO缓存中没有数据了),Read操作通常会直接返回获取到的数据而不是继续等待IO缓存中到达更多的数据
- 当Read操作在成功读取到n字节数据后遇到一个错误或者文件的末尾,它将会返回读取的n字节数据,然后err的返回可能有两种操作:
- 在本次Read操作的时候返回n(>0)和err(非nil)
- 或者本次Read操作返回n(>0)和nil,下一次调用的时候再返回0和err(非nil)
- 这两种操作都是可能的,所以调用者永远应该首先按照n>0来判定是否有数据返回,而不是先判定err是否为nil
- 举个例子说明,当某次调用到达文件末尾并且还读取到了n字节数据的时候,Reader的实现可能有两种方式:
- 当前调用返回n和EOF error
- 当前调用返回n和nil,下次调用返回0和EOF
- Read的实现不应该返回0和nil,也就是当返回0的时候就应该返回一个非nil的error,除非缓冲空间的大小为0,然后调用者应该忽略调用0和nil这种返回值组合,当作什么都没发生,特别强调一下,这个返回并不表示EOF了
————————————————
版权声明:本文为CSDN博主「barryq」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/bob_dadoudou/article/details/79476592