• go特性-defer


    1:后定义的defer先执行(可以理解为栈的方式)

    // 222
    // 111
    func Test1(t *testing.T) {
    	defer fmt.Println("111")
    	defer fmt.Println("222")
    }
    

    2:defer定义的函数的参数,在定义的时候已经被赋值了

    // defer 函数定义的时候,参数已经被赋值了(参数被捕捉了)
    
    // 输出:
    // 第二个defer:  2
    // 第一个defer:  1
    func Test2(t *testing.T) {
    	a := 1
    
    	// 注意这里,a作为defer函数的参数。defer函数定义的时候,就把a的值确定了
    	defer fmt.Println("第一个defer: ", a)
    
    
    	defer func() {
    		fmt.Println("第二个defer: ", a)
    	}()
    
    	a+=1
    }
    

    3:defer函数可以修改具名返回值,但不会修改匿名返回值

    /////////////////////////////////////////////////////////
    // defer 函数可以修改具名返回值,但是不会修改匿名返回值
    // 输出
    //   fHasName: 2
    //   fNoName: 1
    func fHasName() (val int) {
    	val = 1
    	defer func() {
    		// 因为val是个具名返回值,所以这里对val的操作,会影响到返回值
    		val += 1
    	}()
    
    	return val
    }
    func fNoName() int {
    	val := 1
    	defer func() {
    		// 这里的操作则不会影响返回值
    		val += 1
    	}()
    
    	return val
    }
    

    4:遇到panic的时候,当前协程调用栈已定义的defer将被执行,如果当前协程没有任何一个defer函数内执行了recover,那么执行完所有的defer之后,将会触发panic退出进程

    /* 输出
    has: 333
    err: haha
    has: 222
    has: 111
     */
    func  TestHasRecover(t *testing.T)  {
    	defer fmt.Println("has: 111")
    	defer fmt.Println("has: 222")
    	defer func() {
    		if err := recover(); err != nil {
    			fmt.Println("err:", err)
    		}
    	}()
    	defer fmt.Println("has: 333")
    	panic("haha")
    	defer fmt.Println("has: 444")
    }
    
    /* 输出
    has: 333
    has: 222
    has: 111
    
    panic: haha [recovered]
    	panic: haha
    
    goroutine 19 [running]:
    testing.tRunner.func1.1(0x95df20, 0x9b2110)
    	C:/Go/src/testing/testing.go:1076 +0x310
    testing.tRunner.func1(0xc000140480)
    	C:/Go/src/testing/testing.go:1079 +0x43a
     */
    func  TestNoRecover(t *testing.T)  {
    	defer fmt.Println("has: 111")
    	defer fmt.Println("has: 222")
    	defer fmt.Println("has: 333")
    	panic("haha")
    	defer fmt.Println("has: 444")
    }
    

    最后来一道总结题,如下代码会输出什么?

    
    import "testing"
    import "fmt"
    
    func sum(tip string, a int, b int) int {
    	sum := a + b
    	fmt.Printf("tip=%s a=%d b=%d sum=%d
    ", tip, a, b, sum)
    	return sum
    }
    
    func deferSum() {
    	a := 1
    	b := 2
    	defer sum("1tip", a, sum("2tip", a, b))
    	a = 3
    	defer func(b int) {
    		sum("3tip", a, sum("4tip", a, b))
    	}(a)
    	b = 4
    	defer func() {
    		sum("5tip", a, sum("6tip", a, b))
    	}()
    }
    
    func TestDeferSum(t *testing.T) {
    	deferSum()
    }
    

    正确答案如下:

    tip=6tip a=3 b=4 sum=7
    tip=5tip a=3 b=7 sum=10
    tip=4tip a=3 b=3 sum=6
    tip=3tip a=3 b=6 sum=9
    tip=1tip a=1 b=3 sum=4
    
  • 相关阅读:
    iOS开发UI篇—Modal简单介绍
    iOS开发UI篇—APP主流UI框架结构
    A1081. Rational Sum
    A1049. Counting Ones
    A1008. Elevator
    A1104. Sum of Number Segments
    B1003. 我要通过!
    二分查找、two points、排序
    A1069. The Black Hole of Numbers
    A1101. Quick Sort
  • 原文地址:https://www.cnblogs.com/fitness/p/14046592.html
Copyright © 2020-2023  润新知