6.2 函数参数

本篇学习 Go 函数参数写法,并重点掌握可变参数、`slice...` 展开传参与函数内行为。

字数 1013 字

函数参数

概念说明

函数参数用于把数据传入函数,让同一段逻辑可复用。
Go 中最常见的参数形式有:普通参数、同类型合并参数、可变参数(...)。

语法/规则

  1. 普通参数写法:func add(a int, b int)
  2. 同类型参数可合并:func add(a, b int)
  3. 可变参数写法:func sum(nums ...int)
  4. 可变参数在一个函数里只能有一个,并且必须放在参数列表最后。
  5. 调用可变参数函数时,可以传 0 个、1 个或多个同类型值。
  6. 向可变参数函数传切片时,必须写成 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...))
}

输出结果:

1
2
3
4
5
3
7
3
10
18

可变参数深入理解

func sum(nums ...int) 在调用层面看是“可传多个 int”,
但在函数内部,nums 的真实类型是 []int,所以可以直接 lenrange、索引访问。

  1. nums 在函数内可当作切片使用。
  2. 不传参数时,nums 是长度为 0 的切片语义(可正常 range)。
  3. 普通参数和可变参数可以共存,例如 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...) 是把切片元素展开后再传参

注意两点:

  1. 可以直接展开的是“切片”,例如 []int
  2. 数组不能直接展开,需要先切成切片再展开(如 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[:]...))
}

输出结果:

1
2
15
24

常见错误

  1. 把可变参数放在非最后位置,导致语法错误。
  2. 向可变参数函数传切片时漏写 ...,导致类型不匹配。
  3. 在同一个函数里声明多个可变参数,导致编译失败。
  4. 误以为可变参数在函数内部不是切片,从而不会用 len/range 处理它。
  5. 把数组直接写成 sum(arr...),会报错;应写成 sum(arr[:]...)
使用 Hugo 构建
主题 StackJimmy 设计 由 Hobin 魔改
载入天数...载入时分秒...
发表了 0 篇文章 · 发表了 46 篇笔记 · 总计 2 万 5 千字(其中笔记 25104 字)