• golang的defer执行时机案例分析


    package main
    import "fmt"
    
    func calcFunc(x int, y int) int {
    	return x + y
    }
    
    func main() {
    	// defer语句的执行顺序是,从右到左,逆序执行
    	deferDemo()
    
    	// deferDemo1函数
    	demo1 := deferDemo1()
    	fmt.Println(demo1) // 0
    
    	// deferDemo2函数
    	demo2 := deferDemo2()
    	fmt.Println(demo2) // 1
    
    	// deferDemo4
    	demo4 := deferDemo4()
    	fmt.Println(demo4) // 1
    
    	// deferDemo5
    	demo5 := deferDemo5()
    	fmt.Println(demo5) // 1
    
    	// deferDemo6
    	demo6 := deferDemo6()
    	fmt.Println(demo6) // 2
    
    	// 难点解析
    	/*
    		   分析:
    			defer注册顺序:
    			1.defer fmt.Println("AA", calcFunc(x, calcFunc(x, y)))
    			2.defer fmt.Println("BB", calcFunc(x, calcFunc(x, y)))
    			defer执行顺序:
    			1. fmt.Println("BB", calcFunc(x, calcFunc(x, y)))
    			2. fmt.Println("AA", calcFunc(x, calcFunc(x, y)))
    
    	*/
    	x := 1
    	y := 2
    	// 注册的时候 x = 1, y = 2 所以执行的时候x = 1, y = 2
    	defer fmt.Println("AA", calcFunc(x, calcFunc(x, y))) // calcFunc(1,1+2)  // 结果是:4
    	x = 10
    	// 注册的时候x = 10, y = 2 所以执行的时候x = 10, y = 2
    	defer fmt.Println("BB", calcFunc(x, calcFunc(x, y))) // calcFunc(10,10+2) // 结果是:22
    	y = 20
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    分析:
    defer语句的执行顺序是,从右到左,逆序执行
    执行deferDemo()函数时,会先执行defer语句,再执行函数体,函数体执行完后,再执行defer语句
    执行结果:
    开启defer
    结束defer
    defer语句6
    defer语句5
    defer语句4
    defer语句3
    defer语句2
    defer语句1

    func deferDemo() {
    	fmt.Println("开启defer")
    	defer func() {
    		fmt.Println("defer语句1")
    	}()
    	defer func() {
    		fmt.Println("defer语句2")
    	}()
    	defer func() {
    		fmt.Println("defer语句3")
    	}()
    
    	defer fmt.Println("defer语句4")
    	defer fmt.Println("defer语句5")
    	defer fmt.Println("defer语句6")
    
    	fmt.Println("结束defer")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    deferDemo1执行结果是 0,延迟执行

    func deferDemo1() int {
    	var a int
    
    	defer func() {
    		a++
    	}()
    
    	return a
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    deferDemo1执行结果是1:原因返回匿名返回值a等待函数体内操作完成才会执行return

    func deferDemo2() (a int) {
    	// 步骤一先赋值
    	//a = 0
    
    	// 步骤二再执行defer语句
    	defer func() {
    		a++
    	}()
    
    	// 步骤三再执行函数体
    	// 返回值a等待函数体内操作完成才会执行return
    	return a
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    deferDemo3执行结果是1: 原因返回匿名返回值a等待函数体内操作完成才会执行return

    func deferDemo3() (a int) {
    	defer func() {
    		a++
    	}()
    
    	return a
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    deferDemo4

    func deferDemo4() int {
    	x := 1
    
    	defer func(x int) {
    		x++ // 内部x和外面x不是同一个变量
    	}(x)
    
    	return x // 1
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    deferDemo5

    func deferDemo5() (x int) {
    	x = 1
    
    	defer func(x int) {
    		x++ // 内部x和外面x不是同一个变量
    	}(x)
    
    	return x // 1
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    deferDemo6

    func deferDemo6() (x int) {
    	x = 1
    
    	defer func() {
    		x++
    	}()
    
    	return x // 2
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    plsql连接oracle数据库
    在spring里任何位置拿到当前请求的对象
    程序员是如何看待“祖传代码”的?
    【2D/3D RRT* 算法】使用快速探索随机树进行最佳路径规划(Matlab代码实现)
    Linux中nfs:failed: Operation not supported
    基于Python+Html的番剧更新表及番剧详情数据库
    2022广西师范大学暑期训练赛 E ,K
    C/C++输出绝对值 2019年9月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析
    【x265 源码分析系列】:概述
    unity包体相关的加密解密操作
  • 原文地址:https://blog.csdn.net/qq_44472790/article/details/134250470