6.2 函数参数
本篇学习 Go 函数参数写法,并重点掌握可变参数、`slice...` 展开传参与函数内行为。
函数参数
概念说明
函数参数用于把数据传入函数,让同一段逻辑可复用。
Go 中最常见的参数形式有:普通参数、同类型合并参数、可变参数(...)。
语法/规则
- 普通参数写法:
func add(a int, b int)。 - 同类型参数可合并:
func add(a, b int)。 - 可变参数写法:
func sum(nums ...int)。 - 可变参数在一个函数里只能有一个,并且必须放在参数列表最后。
- 调用可变参数函数时,可以传 0 个、1 个或多个同类型值。
- 向可变参数函数传切片时,必须写成
slice...。
参数写法示例
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
| package main
import "fmt"
func add(n1 int, n2 int) int {
return n1 + n2
}
func add1(n1, n2 int) int {
return n1 + n2
}
func add2(numList ...int) int {
sum := 0
for _, num := range numList {
sum += num
}
return sum
}
func main() {
fmt.Println(add(1, 2))
fmt.Println(add1(3, 4))
fmt.Println(add2(1, 2))
fmt.Println(add2(1, 2, 3, 4))
nums := []int{5, 6, 7}
fmt.Println(add2(nums...))
}
|
输出结果:
可变参数深入理解
func sum(nums ...int) 在调用层面看是“可传多个 int”,
但在函数内部,nums 的真实类型是 []int,所以可以直接 len、range、索引访问。
nums 在函数内可当作切片使用。- 不传参数时,
nums 是长度为 0 的切片语义(可正常 range)。 - 普通参数和可变参数可以共存,例如
func report(tag string, nums ...int)。
可变参数调用对比示例
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
| package main
import "fmt"
func sum(nums ...int) int {
total := 0
for _, n := range nums {
total += n
}
return total
}
func showArgs(tag string, nums ...int) {
fmt.Printf("%s -> type=%T len=%d values=%v\n", tag, nums, len(nums), nums)
}
func main() {
fmt.Println(sum())
fmt.Println(sum(1, 2, 3))
base := []int{4, 5, 6}
fmt.Println(sum(base...))
showArgs("直接传值", 8, 9)
showArgs("传切片", base...)
}
|
输出结果:
1
2
3
4
5
| 0
6
15
直接传值 -> type=[]int len=2 values=[8 9]
传切片 -> type=[]int len=3 values=[4 5 6]
|
展开传参(slice...)
fmt.Println(sum(base...)) 这种写法叫“展开传参”。
它的意思是:把切片 base 里的元素逐个拆开,作为多个参数传给 sum。
例如:
sum(1, 2, 3) 是直接传多个参数sum(base...) 是把切片元素展开后再传参
注意两点:
- 可以直接展开的是“切片”,例如
[]int。 - 数组不能直接展开,需要先切成切片再展开(如
arr[:]...)。
展开传参示例(切片与数组)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| package main
import "fmt"
func sum(nums ...int) int {
total := 0
for _, n := range nums {
total += n
}
return total
}
func main() {
base := []int{4, 5, 6}
fmt.Println(sum(base...))
arr := [3]int{7, 8, 9}
fmt.Println(sum(arr[:]...))
}
|
输出结果:
常见错误
- 把可变参数放在非最后位置,导致语法错误。
- 向可变参数函数传切片时漏写
...,导致类型不匹配。 - 在同一个函数里声明多个可变参数,导致编译失败。
- 误以为可变参数在函数内部不是切片,从而不会用
len/range 处理它。 - 把数组直接写成
sum(arr...),会报错;应写成 sum(arr[:]...)。