函数
函数定义
函数定义包括函数名、形式参数列表、返回值列表(可省略)以及函数体
func name(parameter-list) (return-list) {
body
}
参数传递
传递方式
- 值传递。被调函数的形式参数作为被调函数的局部变量处理,即在堆栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值
- 引用传递。被调函数的形式参数虽然也作为局部变量在堆栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过堆栈中存放的地址访问主调函数中的实参变量。因此,被调函数对形参做的任何操作都影响了主调函数中的实参变量
将地址传递和值传递统一起来,归根结底还是传递的是"值"。因此,在 Go 语言中,对于值类型,传递的是值的拷贝,对于引用类型,传递的是地址的拷贝
- 值类型:基础数据类型、数组、结构体
- 引用类型:slice、map、函数、指针
可变参数
在声明可变参数函数时,需要在参数列表的最后一个参数类型之前加上省略符号 “...”,这表示该函数会接收任意数量的该类型参数
func sum(vals ...int) int {
total := 0
for _, val := range vals {
total += val
}
return total
}
匿名函数
拥有函数名的函数只能在包级语法块中被声明,通过函数字面量(function literal),我们可绕过这一限制,在任何表达式中表示一个函数值。函数字面量的语法和函数声明相似,区别在于 func 关键字后没有函数名。函数值字面量是一种表达式,它的值被称为匿名函数(anonymous function)
func(i, j int) bool {
}
defer 函数
一个 defer 语句就是一个普通的函数或方法调用。 defer 语句保证了不论是在正常情况下(return 返回), 还是非正常情况下(发生错误,程序终止),函数或方法都能够执行
- 函数内可以定义多个
defer语句或函数,调用顺序和定义的顺序相反 defer的执行顺序在return之后,但是在返回值返回给调用方之前,所以使用defer可以达到修改返回值的目的
闭包
闭包(closure)是一个函数以及其捆绑的周边环境状态的引用的组合。 换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。闭包会随着函数的创建而被同时创建
特性
- 记忆特性。闭包可以记忆创建时的环境,并且一直保持对该环境的绑定,直到闭包被销毁
- 延迟绑定。闭包会在使用时实际读取环境变量值,而不是取生成闭包时的环境变量值