4.2 Go 可变参数函数学习笔记
1. 可变参数函数基本语法 — ...type
可变参数(variadic)函数接受任意数量的参数,函数内部将它们作为切片处理:
package main
import "fmt"
// ...int 表示可以传入任意数量的 int 参数
// 函数内部 numbers 是 []int 切片类型
func sum(numbers ...int) int {
total := 0
for _, num := range numbers {
total += num
}
return total
}
func main() {
// 不传参数:numbers 为空切片 [],sum 为 0
result0 := sum()
fmt.Println("Sum of no numbers:", result0)
// 传 3 个参数:numbers = [1, 2, 3]
result1 := sum(1, 2, 3)
fmt.Println("Sum of 1, 2, 3:", result1)
// 传 5 个参数:numbers = [10, 20, 30, 40, 50]
result2 := sum(10, 20, 30, 40, 50)
fmt.Println("Sum of 10, 20, 30, 40, 50:", result2)
}
执行结果:
Sum of no numbers: 0
Sum of 1, 2, 3: 6
Sum of 10, 20, 30, 40, 50: 150
要点:
-
func sum(numbers ...int)—...int是可变参数语法,表示"任意数量的 int" - 函数内部
numbers的类型是[]int(切片),可以用range遍历 - 调用时可以传 0 个、1 个、2 个、任意多个参数:
sum()、sum(1,2,3)、sum(10,20,30,40,50) - 传 0 个参数时,
numbers是空切片[]int{},循环不执行,total 为 0 - 可变参数必须是函数的最后一个参数:
func format(prefix string, values ...int) string { ... } // 正确 func format(values ...int, prefix string) string { ... } // 编译报错
2. 展开切片传入 — slice...
如果已有切片数据,用 slice... 展开传入可变参数函数:
package main
import "fmt"
func sum(numbers ...int) int {
total := 0
for _, num := range numbers {
total += num
}
return total
}
func main() {
// 已有切片数据
numbers := []int{1, 2, 3, 4, 5}
// 用 ... 展开切片传入
result3 := sum(numbers...)
fmt.Println("Sum of slice:", result3)
// 不能直接传切片:sum(numbers) 编译报错
// 必须用 sum(numbers...) 展开
}
执行结果:
Sum of slice: 15
要点:
-
sum(numbers...)—...是展开操作符,把切片[1,2,3,4,5]展开为独立参数1,2,3,4,5 - 等价于
sum(1, 2, 3, 4, 5),但更方便(不需要手动拆开切片) -
sum(numbers)不带...会编译报错:因为numbers是[]int,不是...int -
...展开只能用于与可变参数类型相同的切片:[]int展开给...int,[]string展开给...string - 实际场景:对已有数据批量调用可变参数函数,如
fmt.Println(strings...)展开字符串切片
3. 可变参数遍历与格式化输出
可变参数函数可以用 range 遍历,利用索引做格式化:
package main
import "fmt"
func printAll(items ...string) {
for i, item := range items {
fmt.Printf("%d: %s\n", i+1, item)
}
}
func main() {
printAll("apple", "banana", "cherry")
}
执行结果:
1: apple
2: banana
3: cherry
要点:
-
items ...string— 可变参数类型可以是任何类型(int、string、float64 等) -
range items遍历切片,i是索引(从 0 开始),i+1转为序号(从 1 开始) -
fmt.Printf("%d: %s\n", i+1, item)—%d格式化序号,%s格式化字符串 -
printAll("apple", "banana", "cherry")— 传入 3 个字符串参数 - Go 标准库中大量使用可变参数:
-
fmt.Println(a, b, c)—func Println(a ...interface{}) -
fmt.Printf(format, a, b)—func Printf(format string, a ...interface{}) -
append(slice, elem1, elem2)—func append(slice []T, elems ...T) []T
-
知识点总结
| 知识点 | 关键概念 |
|---|---|
| 可变参数语法 |
func name(args ...type) — 函数内部作为切片处理 |
| 调用方式 | 传任意数量参数(0个也行),或用 slice... 展开切片 |
| 展开操作符 |
sum(slice...) 把切片展开为独立参数,不带 ... 编译报错 |
| 位置限制 | 可变参数必须是最后一个参数 |
| 标准库示例 |
fmt.Println、fmt.Printf、append 都是可变参数函数 |