#《Go 语音圣经(中文版)》

#可变参数

在声明可变参数函数时,需要在参数列表的最后一个参数类型之前加上省略符号...,这表示该函数会接收任意数量的该类型参数。

调用者隐式的创建一个数组,并将原始参数复制到数组中,再把数组的一个切片作为参数传给被调用函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

import "fmt"

/*
@Time : 2021/6/5 16:04
@Author : onns
@File : ch5/sum/sum.go
*/

func sum(vals ...int) int {
total := 0
for _, val := range vals {
total += val
}
return total
}

func f(...int) {}
func g([]int) {}

func main() {
fmt.Println(sum())
fmt.Println(sum(3))
fmt.Println(sum(1, 2, 3, 4))

values := []int{1, 2, 3, 4}
fmt.Println(sum(values...))

fmt.Printf("%T\n", f)
fmt.Printf("%T\n", g)
}
1
2
3
4
5
6
7
[16:13:49] onns@Onns ~/Onns/code/go/go-bible/ch5 $ go run sum/sum.go
0
3
10
10
func(...int)
func([]int)

如果原始参数已经是切片类型,只需在最后一个参数后加上省略符。

1
2
values := []int{1, 2, 3, 4}
fmt.Println(sum(values...))

虽然在可变参数函数内部,...int型参数的行为看起来很像切片类型,但实际上,可变参数函数和以切片作为参数的函数是不同的

1
2
3
4
func f(...int) {}
func g([]int) {}
fmt.Printf("%T\n", f) // "func(...int)"
fmt.Printf("%T\n", g) // "func([]int)"

许多文件系统,尤其是NFS,写入文件时发生的错误会被延迟到文件关闭时反馈。如果没有检查文件关闭时的反馈信息,可能会导致数据丢失,而我们还误以为写入操作成功。如果io.Copy和f.close都失败了,我们倾向于将io.Copy的错误信息反馈给调用者,因为它先于f.close发生,更有可能接近问题的本质。