跳转到主要内容
模块 3 · 第 2 课(共 5)课程中的12/50~12 min
模块课程(2/5)

多重返回和命名返回

在 Go 中,一个函数可以返回多个值。就是这个机制 启用您已经见过且普遍存在的 (value, error) 模式 整个标准库。

多重回报

返回类型位于括号之间,以逗号分隔:

Go
func divmod(a, b int) (int, int) {
    return a / b, a % b
}

q, r := divmod(17, 5) // q=3, r=2

它们通过多重赋值被解构。丢弃其中之一 值使用 _:

Go
_, r := divmod(17, 5) // solo il resto

规范的 (T, error) 模式

几乎所有的 stdlib 都遵循它。 error 始终是最后一个:

Go
func read(path string) ([]byte, error) {
    data, err := os.ReadFile(path)
    if err != nil {
        return nil, fmt.Errorf("read %q: %w", path, err)
    }
    return data, nil
}

命名回报

您可以命名返回值:它们成为预先声明的变量 初始化为零,并且不带参数的 return 返回它们(“裸 返回”):

Go
func divmod(a, b int) (q, r int) {
    q = a / b
    r = a % b
    return       // naked: ritorna q, r
}

命名返回也会出现在文档工具提示中,因此它们很有用 作为复杂功能的 内联文档 的一种形式 - 不仅仅是 为了赤裸裸的回归。

超过两次回报?

没有什么可以阻止您使用 (int, int, int, error),但如果您觉得有必要 这几乎总是表明您应该返回一个结构:

Go
type Result struct {
    Sum  int
    Avg  float64
    Max  int
}

func analyze(nums []int) (Result, error) { ... }

尝试一下

锻炼#go.m3.l2.e1
尝试:0加载中...

定义返回商和余数的 divmod(a, b int) (int, int)。

正在加载编辑器...
显示提示

括号之间的返回类型:`(int, int)`。

3 次尝试后可用的解决方案

锻炼#go.m3.l2.e2
尝试:0加载中...

实现 safeDiv(a, b int) (int, error):如果 b == 0 return (0, error.New('divisione per Zero')),否则 (a/b, nil)。

正在加载编辑器...
显示提示

错误始终为最后一个值。错误时:零值+错误。

3 次尝试后可用的解决方案

Quiz#go.m3.l2.e3
准备好

该程序使用命名返回打印什么?

Go
func f() (a, b int) {
    a = 1
    b = 2
    return
}
x, y := f()
fmt.Println(x, y)
答案选项

回顾

  • 括号之间的多个值:func f() (T1, T2, error)。
  • 约定:error 始终作为最后一个值;错误时,零值+错误。
  • 命名返回预先声明变量并启用裸返回。
  • 仅在非常短的函数中裸返回;除此之外,可读性就会受到影响。
  • 超过2-3次回报?您可能想要一个结构。