In Go, when a function returns an error, are the other variables always its "zero" value?

huangapple go评论70阅读模式
英文:

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 (
	&quot;bufio&quot;
	&quot;fmt&quot;
	&quot;io&quot;
	&quot;os&quot;
)

func main() {
	f, err := os.Open(&quot;readfile.go&quot;)
	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 &amp;&amp; err != io.EOF {
			fmt.Println(err)
			return
		}
	}
	fmt.Println(&quot;file length:&quot;, fileLen, &quot;bytes&quot;)
}

If err != nil then, unless the documentation says otherwise, assume that all other values are undefined.

huangapple
  • 本文由 发表于 2016年1月23日 11:54:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/34959422.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定