defer关键字

什么是 defer

defer 是 Go 语言提供的一种用于注册延迟调用的机制,每一次 defer 都会把函数压入栈中,当前函数返回前再把延迟函数取出并执行。

1.defer 和panic 一起使用时执行顺序?

package main
 
import (
     "fmt"
)
func main() {
    defer_call()
}

func defer_call() {
    defer func() { fmt.Println("打印前") }()
    defer func() { fmt.Println("打印中") }()
    defer func() { fmt.Println("打印后") }()

    panic("触发异常")
}

defer 的执行顺序是后进先出。当出现 panic 语句的时候,会先按照 defer 的后进先出的顺序执行,最后才会执行panic。

2.defer 和带命名返回参数的函数一起使用

func f1() (r int) {
    defer func() {
        r++
    }()
    return 0
}

该程序的执行步骤为 1:r = return xxx,2  调用defer,3 return

因此该程序执行的结果为1.

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

1: r=t=5,2 defer,3 return 

因为 defer 是对t 的操作,和r没有关系,所以程序返回值为5、

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

1:r =1,2.defer 3. return

因为defer 是对局部变量的修改,不影响实参,因此返回值为1.

 

3. defer 和匿名返回值一起使用

func increaseA() int {
    var i int
    defer func() {
        i++
    }()
    return i
}

对于匿名返回值来说,可以假设有一个返回值。设为tmp。

因此1:tmp=i=0,2:defer 3:return

所以defer修改的是i的值,和tmp没有关系,因此返回值为0.

 

4.defer 遇见return

var a bool = true
func main() {
    defer func(){
        fmt.Println("1")
    }()
    if a == true {
        fmt.Println("2")
        return
    }
    defer func(){
        fmt.Println("3")
    }()
}

该程序输出 2 1,defer 遇见return 不会执行。

5.

对于一个延迟函数的调用,它的实参是在此调用被推入延迟调用栈的时候被估值的

对于一个协程调用,它的实参是在此协程被创建的时候估值的

一个匿名函数体内的表达式是在此函数被执行的时候才会被逐个估值的。不管此函数是被普通函数还是延迟/协程调用

func F(n int) func() int {
    return func() int {
        n++
        return n
    }
}

func main() {
    f := F(5)
    defer func() {
        fmt.Println(f())
    }()//参见第三条,// 执行的时候才确定,因此为8
    defer fmt.Println(f()) //参见第一条,因此入栈值确定为6.
    i := f()
    fmt.Println(i)//直接调用,因为值为7.
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值