golang defer的理解

1.执行顺序

首先看下面这个程序,写出它打印的结果

package main

import (
    "fmt"
)

func main() {
    d()
}

func d() {
    defer func() { fmt.Println("打印前") }()
    defer func() { fmt.Println("打印中") }()
    defer func() { fmt.Println("打印后") }()
    panic("触发异常")
}

defer 是后进先出。
panic 需要等defer 结束后才会向上传递。 出现panic的时候,会先按照defer的后入先出的顺序执行,最后才会执行panic。所以最终的打印结果:

打印后
打印中
打印前
panic: 触发异常

2.内置函数

再看一看这个程序

func calc(index string, a, b int) int {
    ret := a + b
    fmt.Println(index, a, b, ret)
    return ret
}

func main() {
    a := 1
    b := 2
    defer calc("1", a, calc("10", a, b))
    a = 0
    defer calc("2", a, calc("20", a, b))
    b = 1
}

最终的输出会是什么呢,如果按照defer的思想后进显出是不是到第2个defer完成的时候第一个defer中的a为0,b为1呢,虽然defer是后进先出,但defer表达式中的函数确是顺序执行的,所以最先被调用calc(“10”,1,2)>10,1,2,3 执行index:2时,与之前一样,需要先调用calc(“20”,0,2)>20,0,2,2 执行到b=1时候开始调用,index:2==>calc(“2”,0,2)>2,0,2,2 最后执行index:1>calc(“1”,1,3)==>1,1,3,4
所以最后输出的结果是:

10 1 2 3
20 0 2 2
2 0 2 2
1 1 3 4

3.作用域

最后一个题:

func main() {

	println(DeferFunc1(1))
	println(DeferFunc2(1))
	println(DeferFunc3(1))
}

func DeferFunc1(i int) (t int) {
	t = i
	defer func() {
		t += 3
	}()
	return t
}

func DeferFunc2(i int) int {
	t := i
	defer func() {
		t += 3
	}()
	return t
}

func DeferFunc3(i int) (t int) {
	defer func() {
		t += i
	}()
	return 2
}

根据上面的粒子,这里就是调用了三个函数,而且defer在函数里面,是否就是按照程序的执行思路输出 4,4,2 呢,很显然没有那么简单,需要明确一点是defer需要在函数结束前执行。 函数返回值名字会在函数起始处被初始化为对应类型的零值并且作用域为整个函数 DeferFunc1有函数返回值t作用域为整个函数,在return之前defer会被执行,所以t会被修改,返回4; DeferFunc2函数中t的作用域为函数,返回1; DeferFunc3返回3,结果就是4,1,3

这上面的三道题,是否加深了小伙伴们对defer的理解呢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值