函数定义
func function_name( [parameter list] ) [return_types] {
函数体
}
- func:关键词
- function_name:函数名称,遵循驼峰命名法,首字母若小写则只可本包内调用,若大写则可以在其他包内调用。
- parameter list:参数列表,参数个数不限。
- return_types:返回类型
函数参数
值传递
值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。 假如我们定义一个函数用于交换两个变量的值
func changeNum(a int,b int){
var t int = 0
t = a
a = b
b = t
}
func main(){
a := 1
b := 2
fmt.Printf("交换前:a = %v , b = %v.",a,b) // 交换前:a = 1 , b = 2.
changeNum(a,b)
fmt.Printf("交换后:a = %v , b = %v.",a,b) // 交换后:a = 1 , b = 2.
}
引用传递
引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。 同样是交换两个变量的例子,假如我们使用引用传递的话,在主函数中测试变量的值就会发生改变
func changeNum(a *int,b *int){
var temp int
temp = *a
*a = *b
*b = temp
}
func main(){
a := 1
b := 2
fmt.Printf("交换前:a = %v , b = %v.",a,b) // 交换前:a = 1 , b = 2.
changeNum(&a,&b) // 调用函数,传入的是a,b两个值的地址
fmt.Printf("交换后:a = %v , b = %v.",a,b) // 交换后:a = 2 , b = 1.
}
init 函数
init 函数是初始化函数,可以用来进行一些初始化操作,每一个源文件都可以包含一个 init 函数,该函数会在 main 函数之前执行。
func init(){
fmt.Println("init函数被调用了")
}
func main(){
fmt.Println("main函数被调用了")
}
执行以上代码,结果是:
init函数被调用了
main函数被调用了
匿名函数
定义
匿名函数是指不需要定义函数名的一种函数实现方式,匿名函数没有函数名只有函数体,由一个不带函数名的函数声明和函数体组成。
使用
- 在定义时调用匿名函数
func(num int){
fmt.Printf("num = %v",num)
}(10)
- 将匿名函数的值返回给变量
fn := func(num int){
fmt.Printf("num = %v",num)
}
fn(10)
闭包
定义
闭包是引用了自由变量的函数,被引用的自由变量和函数一同存在,即使已经离开了自由变量的环境也不会被释放或者删除,在闭包中可以继续使用这个自由变量,简单点说就是 函数 + 引用环境 = 闭包
示例
func addNum () func (int) int{
var sum int = 0
return func (num int) int{
sum+=num
return sum
}
}
func main(){
fn := addNum()
fmt.Println(fn(1)) // 1
fmt.Println(fn(1)) // 2
fmt.Println(fn(1)) // 3
}
闭包中的变量,可以一直保存
defer 关键字
Go语言的 defer 语句会将其后面跟随的语句进行延迟处理,在 defer 归属的函数即将返回时,将延迟处理的语句按 defer 的逆序进行执行,也就是说,先被 defer 的语句最后被执行,最后被 defer 的语句,最先被执行。
多个 defer 执行顺序
func main() {
fmt.Println("defer begin")
// 将defer放入延迟调用栈
defer fmt.Println(1)
defer fmt.Println(2)
// 最后一个放入, 位于栈顶, 最先调用
defer fmt.Println(3)
fmt.Println("defer end")
}
输出结果:
defer begin
defer end
3
2
1
代码的延迟顺序与最终的执行顺序是反向的。延迟调用是在 defer 所在函数结束时进行,函数结束可以是正常返回时,也可以是发生宕机时。 如果像下方代码:
func main() {
fmt.Println("print begin")
print()
fmt.Println("print end")
}
func print() {
fmt.Println("defer begin")
defer fmt.Println(1)
defer fmt.Println(2)
fmt.Println("defer end")
}
输出结果:
print begin
defer begin
defer end
2
1
print end