Golang函数的参数

Golang中的函数可以有0或多个参数,参数需要指定数据类型。

声明函数时的参数列表叫做形参,调用时传递的参数叫做实参。

Golang中是通过传值的方式传参的,意味着传递给函数的是拷贝后的副本,所以函数内部访问、修改的也是这个副本。

Golang中可以使用变长参数,有时候并不能确定参数的个数,可以使用变长参数,可以在函数定义语句的参数部分使用ARGS...TYPE的方式。这时会将...代表的参数全部保存到一个名为ARGS的slice中,注意这些参数的数据类型都是TYPE。

Golang中函数的参数实例

Golang传参

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main

import "fmt"

//形参
func f1(a int, b int) int {
if a > b {
return a
} else {
return b
}
}

func main() {
//实参
r := f1(1, 2)
fmt.Printf("r: %v\n", r)
}

演示参数传递,按值传递

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main

import "fmt"

func f1(a int) {
a1 := 200
fmt.Printf("a1: %v\n", a1)
}

func main() {
a := 100
f1(a)
fmt.Printf("a: %v\n", a)
}

运行结果:

1
2
a1: 200
a: 100

从运行结果可以看到,调用函数f1后,a的值并没有被改变,说明参数传递是拷贝了一个副本,也就是拷贝了一份新的内容进行运算。

Tips

mapsliceinterfacechannel这些数据类型本身就是指针类型的,所以就算是拷贝传值也就是拷贝的指针,拷贝后的参数仍然指向底层数据结构,所以修改它们可能会影响外部数据结构的值。

切片类型

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import "fmt"

func f2(s []int) {
s[0] = 1000
}

func main() {
s := []int{1, 2, 3}
f2(s)
fmt.Printf("s: %v\n", s)
}

运行结果:

1
s: [1000 2 3]

从运行结果看,调用函数后,slice内容被改变了

变长参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main

import "fmt"

func f3(args ...int) {
for _, v := range args {
fmt.Printf("v: %v\n", v)
}
}

func f4(name string, ok bool, args ...int) {
fmt.Printf("name: %v\n", name)
fmt.Printf("ok: %v\n", ok)
for _, v := range args {
fmt.Printf("v: %v\n", v)
}
}

func main() {
f3(1, 2, 3)
f3(2, 3, 4, 5, 6)
f4("weiyunfeng", true, 1, 2, 3)
}

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
v: 1
v: 2
v: 3
v: 2
v: 3
v: 4
v: 5
v: 6
name: weiyunfeng
ok: true
v: 1
v: 2
v: 3