zoukankan      html  css  js  c++  java
  • go09---defer

    package main
    
    /*
    defer
    
    类似其它语言中的析构函数,在函数体执行结束后
    按照调用顺序的相反顺序逐个执行,先进后出,
    即使函数发生严重错误也会执行,资源清理文件关闭,
    支持匿名函数的调用
    常用于资源清理、文件关闭、解锁以及记录时间等操作
    通过与匿名函数配合可在return之后修改函数计算结果
    如果函数体内某个变量作为defer时匿名函数的参数,则在定义defer
    时即已经获得了拷贝,如果不是参数则是引用某个变量的地址
    
    Go 没有异常机制,但有 panic/recover 模式来处理错误
    Panic 可以在任何地方引发,但recover只有在defer调用的函数中有效
    
    */
    
    import (
        "fmt"
    )
    
    func main1() {
        fmt.Println("a")
        defer fmt.Println("b")
        defer fmt.Println("c") //acb,相反顺序逐个执行,先进后出,
    }
    
    func main2() {
        fmt.Println("a")
        defer fmt.Println("b")
        defer fmt.Println("c")
    
        for i := 0; i < 3; i++ {
            defer fmt.Println(i)
        } //    a 2 1 0 c b
    }
    
    func main3() {
        for i := 0; i < 3; i++ {
            defer func() {
                fmt.Println(i)
            }() // 3 3 3,for循环结束的时候i=3,而当main函数结束的时候开始执行defer,此时i一直是3(存在闭包)
        }
    }
    
    //go语言没有异常机制,也就是没有try catch,defer就类似于finally,
    //go语言的异常机制是panic/recover 模式来处理错误,Panic 可以在任何地方引发,但recover只有在defer调用的函数中有效
    //函数发生错误的时候,函数已经不执行了,只能靠defer来执行一些恢复操作,所以recover只能放在defer调用的函数中才是有意义的。
    
    func main4() {
        A()
        B()
        C() //AAAAAAA,   panic:BBBBBBBB
    }
    
    func A() {
        fmt.Println("AAAAAAA")
    }
    
    func B() {
        panic("BBBBBBBB") //B已经panic了,C函数不执行,程序终止执行了,
    }
    
    func C() {
        fmt.Println("VCCCCCC")
    }
    
    func main() {
        A1()
        B1()
        C1()
        //AAAAAAA   recover in B     VCCCCCC
        //通过defer将程序从panic状态恢复回来,恢复到正常执行,
    }
    
    func A1() {
        fmt.Println("AAAAAAA")
    }
    
    func B1() {
        //恢复panic,要写在panic之前,因为如果执行了panic了后面的代码不再执行了,
        //那么defer就注册不了recover函数了,(defer函数是在函数执行完之后执行的,相当于只是注册了里面的一些函数)
        defer func() {
            if err := recover(); err != nil { //err为函数中出现的错误,err不为空,引发了panic,说明revcover有效,恢复panic,
                fmt.Println("recover in B")
            }
        }()
        panic("BBBBBBBB") //B已经panic了,C函数不执行,程序终止执行了,
    }
    
    func C1() {
        fmt.Println("VCCCCCC")
    }

    slice和map是引用类型, 

    匿名函数不能作为顶级函数,只能够放在函数里面,

    panic和recover类似于其他语言的try catch,用于异常的返回和错误的处理  。出现了错误panic,要从错误中恢复过来,  程序进入panic之后函数不再执行(类似于发生了错误跑出了异常),要想在panic之后仍然能够执行recover函数就需要用到defer,defer是不管任何情况都会执行用defer定义的函数,将recover放在defer中,并且defer要放在可能发生panic的语句之前,

  • 相关阅读:
    html5+plus(5+app) 扫一扫(plus.barcode)
    uniapp地图控件(浅显使用)
    sku排列算法,库存类展示(规格,型号,颜色等)
    『嗨威说』数据结构中常用的查找算法思路总结
    『ACM C++』 PTA 天梯赛练习集L1 | 057-063
    『ACM C++』 PTA 天梯赛练习集L1 | 054-056
    『ACM C++』 PTA 天梯赛练习集L1 | 052-053
    『ACM C++』 PTA 天梯赛练习集L1 | 050-51
    『ACM C++』 PTA 天梯赛练习集L1 | 048-49
    『ACM C++』 PTA 天梯赛练习集L1 | 046-47
  • 原文地址:https://www.cnblogs.com/yaowen/p/8074529.html
Copyright © 2011-2022 走看看