英文:
In Go, when a function returns an error, are the other variables always its "zero" value?
问题
我正在谈论Go标准库:
output, err := abc.Xyz()
if err != nil {
// 根据约定,`output` 总是它的“零”值吗?
}
英文:
I'm talking about the Go standard library:
output, err := abc.Xyz()
if err != nil {
// by convention is `output` always its "zero" value?
}
答案1
得分: 5
并不总是这样。例如,io.Reader
:
> io 包
>
> Reader 类型
>
> type Reader interface {
> Read(p []byte) (n int, err error)
> }
>
> Reader 是包装基本 Read 方法的接口。
>
> Read 将最多 len(p) 个字节读入 p 中。它返回读取的字节数 n(0 ≤ n ≤ len(p))和遇到的任何错误。即使 Read 返回 n < len(p),它也可能在调用期间使用 p 的全部作为临时空间。如果有一些数据可用但不足 len(p) 个字节,Read 通常会返回可用的数据,而不是等待更多数据。
>
> 当 Read 在成功读取 n > 0 个字节后遇到错误或文件结束条件时,它返回读取的字节数。它可能返回相同调用的(非 nil)错误,也可能返回后续调用的错误(和 n == 0)。一个常见情况是,返回一个非零字节数的 Reader 在输入流的末尾可能返回 err == EOF 或 err == nil。下一次 Read 应该返回 0, EOF。
>
> 调用者应始终在考虑错误 err 之前处理返回的 n > 0 个字节。这样做可以正确处理在读取一些字节后发生的 I/O 错误,以及两种允许的 EOF 行为。
>
> Read 的实现应避免在返回 nil 错误的情况下返回零字节计数,除非 len(p) == 0。调用者应将返回的 0 和 nil 视为表示什么都没有发生;特别是它不表示 EOF。
>
> 实现不得保留 p。
例如,
readfile.go
:
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
f, err := os.Open("readfile.go")
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
r := bufio.NewReader(f)
fileLen := int64(0)
buf := make([]byte, 0, 4*1024)
for {
n, err := r.Read(buf[:cap(buf)])
buf = buf[:n]
if n == 0 {
if err == nil {
continue
}
if err == io.EOF {
break
}
fmt.Println(err)
return
}
// 对 buf 做一些操作
fileLen += int64(len(buf))
if err != nil && err != io.EOF {
fmt.Println(err)
return
}
}
fmt.Println("文件长度:", fileLen, "字节")
}
如果 err != nil
,除非文档另有说明,否则假设所有其他值都是未定义的。
英文:
Not always. For example,io.Reader
:
> Package io
>
> type Reader
>
> type Reader interface {
> Read(p []byte) (n int, err error)
> }
>
> 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.
For example,
readfile.go
:
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
f, err := os.Open("readfile.go")
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
r := bufio.NewReader(f)
fileLen := int64(0)
buf := make([]byte, 0, 4*1024)
for {
n, err := r.Read(buf[:cap(buf)])
buf = buf[:n]
if n == 0 {
if err == nil {
continue
}
if err == io.EOF {
break
}
fmt.Println(err)
return
}
// Do something with buf
fileLen += int64(len(buf))
if err != nil && err != io.EOF {
fmt.Println(err)
return
}
}
fmt.Println("file length:", fileLen, "bytes")
}
If err != nil
then, unless the documentation says otherwise, assume that all other values are undefined.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论