go语言函数的参数,形参、实参和可变参数
什么是形参,什么是实参
go语言当中,绝大部分的情况下,参数的传递形式是通过形参的方式来传递的。当相对于函数的全局变量以形参(拷贝)的形式传递给函数之后,然后经过函数的处理,该参数的值并不会发生改变。实参则通过指针或引用(传递内存地址)的方式来传递,并且经过函数处理后,值会发生改变。至于什么全局变量和局部变量,大家可以参考python变量作用域,局部变量和全局变量,里面有较为详细的介绍,虽然python和go分属两种计算机语言,但形式不同,原理相通。
go语言形参和实参实例
package main
import "fmt"
func sum1(a int, b int) int {
return a + b
}
func sum2(a *int, b *int) (int, int, int) { //通过指针*传入实参
*a = *a + 1
*b = *b + 1
c := *a + *b
return *a, *b, c
}
func main() {
a := 1
b := 2
x := sum1(a, b)
fmt.Println(x, a, b)
na, nb, c := sum2(&a, &b) //&寻址符号或引用符号,将变量a,b作为指针传入的方式
fmt.Println(a, b, na, nb, c)
}
代码输出:
3 1 2
2 3 2 3 5 //从输出可发现,参数以实参传递之后,原变量的值发生了改变
传递实参,也就是传递指针作为参数有什么用处
- 传递指针最大的好处在于传递指针的时候只是传递了变量的内存地址,非常轻量级,大概只有8bytes,这在传递体积较大的结构体(因为结构体是很多字段、属性的封装容器)的时候,可以避免传递形参所需要的拷贝时所带来的的系统开销,这就大大地优化了程序代码的性能;
- 传递指针,可以使得多个函数都能操作同一个对象,不过这也是其缺点之一,因为全局变量的值被修改之后,可能忘记这个已经被修改的事情了,就像c/c++要释放内存(垃圾回收)一样,有可能会忘记,所以go语言(自动垃圾回收释放内存)的计算机语言就被设计出来了。
go语言函数的可变参数
go语言函数的变参形式如下:
fuc func_name(arg...type){}
注意,arg可以看作是一个slice(实际上不能传递一个slice),其参数的类型要保持一致,接下来我们来实现一个求slice元素之和的实例,代码如下:
package main
import "fmt"
func sum_slice(args ...int) int {
sum := 0
for _, i := range args { //for循环我们将在后面的章节中进行介绍
sum = sum + i
}
return sum
}
func main() {
sum := sum_slice(1, 2, 3, 4, 5)
fmt.Println(sum)
}
代码输出:
15