【golang】defer

145 阅读1分钟

defer概述

使用关键字defer向函数注册退出调用,即主函数退出时,defer后的函数才被调用。defer语句的作用是不管程序是否出现异常,均在函数退出时自动执行相关代码。

defer规则

规则一:当defer被声明时,其(defer函数)参数就会被实时解析

package main

import "fmt"

func main() {
	test()
}

func test() {
	i := 0
	defer fmt.Println(i)
	i++
	defer fmt.Println(i)
}

上述代码输出:1、0

规则二:defer执行顺序为先进后出

package main

import "fmt"

func main() {
	test()
}

func test() {
	for i := 0; i < 5; i++ {
		defer fmt.Println(i)
	}
}

上述代码输出:4、3、2、1、0

规则三:defer可以读取有名返回值并有能力修改它

package main

import "fmt"

func main() {
	t := test()
	fmt.Println(t)
}

func test() (i int) {
	defer func() { i++ }()
	return 1
}

上述代码输出:2

test函数的返回值初始值为0,return的时候赋值为1,之后在返回前被defer加1

其他

案例1

package main

import "fmt"

func main() {
	test()
}

func test() {
	for i := 0; i < 5; i++ {
		defer func() {
			fmt.Println(i)
		}()
	}
}

上述代码输出:5、5、5、5、5

案例2

package main

import "fmt"

func main() {
	test()
}

func test() {
	for i := 0; i < 5; i++ {
		defer func(n int) {
			fmt.Println(n)
		}(i)
	}
}

上述代码输出:4、3、2、1、0

案例3

package main

import "fmt"

func main() {
	fmt.Println(test())
}

func test() int {
	t := 5
	defer func() {
		t++
	}()
	return t
}

上述代码输出:5

案例4

package main

import "fmt"

func main() {
	fmt.Println(test())
}

func test() (t int) {
	t = 5
	defer func() {
		t++
	}()
	return t
}

上述代码输出:6

案例5

package main

import "fmt"

func main() {
	fmt.Println(test())
}

func test() (r int) {
	defer func(r int) {
		r = r + 5
	}(r)
	return 1
}

上述代码输出:1