美文网首页
延迟语句--defer

延迟语句--defer

作者: Caesar_emperor | 来源:发表于2019-08-11 11:16 被阅读0次

    一、初识defer

    func main(){
        defer fmt.println("world")
        fmt.println("hello")
    }

    ==>hello
          world
    =>defer语句会在函数最后执行,被延迟操作的是defer后面的内容

    二、特点

    defer后面的表达式必须是外部函数的调用.上面的例子是针对fmt.println函数的延迟调用

    1)只有当defer语句全部执行,defer所在的函数才能算真正结束执行

    2)当函数中有defer语句时,需要等待所有defer语句执行完毕,才会执行return语句

    =》defer常用于回收资源,清理收尾

    func print(){
        fmt.println("hello")
    }
    func main(){
        for ;i<5;i++{
            defer print()
        }
    }
    ==>5,5,5,5,5

    func print(i int){
        fmt.println(i)
    }
    func main(){
        for ;i<5;i++{
            defer print(i)
        }
    }
    ==>4,3,2,1,0(相当于先储存(0,1,2,3,4)),在输出(4,3,2,1,0)【这也是所谓的后进先出】

    一道考察defer与命名返回值的题目

    返回4,1,3
    解释:
    defer和return以及返回值的关系是defer最先执行一些收尾工作,然后return执行,return负责将结果写入返回值,最后函数携带当前返回值退出,所以:

    func a()(i int){
        defer funcA(){
        }
        defer funcB(){
        }
    }
    先运行funcB再运行funcA

    回到上面的代码,DeferFunc2 函数没有可命名结果形参,t只是个普通局部变量,defer无法对返回值做修改;DeferFunc1 和DeferFunc3的运行逻辑是:

    DeferFunc1:
    t:= 0
    t = 1
    t +=3 -> t = 4

    DeferFunc3:
    t:=0
    t = 2
    t += 1 -> t = 3

    对于返回值是否命名关乎到main函数内调用其他含有defer的函数时,是否可以获取真实的返回值,即没命名返回0,有命名返回最后一次defer的输出。

    三.代码跟踪

    func main(){
        b()
    }
    func a(){
        defer un(trace("a")) //初始化defer函数的参数,所以输出trace()的结果
        fmt.Println("a的逻辑代码")
    }
    func a(){   
       defer un(trace("a"))   
       fmt.Println("b的逻辑代码")
       a()
    }
    func trace(s string)string{
        fmt.Println("开始执行",s)
        return s
    }
    func un(s string){
        fmt.Println("结束执行",s)
    }
    =>开始执行b
        b的逻辑代码
        开始执行a
        a的逻辑代码
        结束执行a
        结束执行b

    相关文章

      网友评论

          本文标题:延迟语句--defer

          本文链接:https://www.haomeiwen.com/subject/wnvjjctx.html