go語言之defer

來源:互聯網
上載者:User
/*1 適用於函數和方法,只能跟方法或者函數*//*2 defer語句順延強制直到函數return或者panicreturn函數不是原子級,包括寫入返回參數及函數返回,defer語句在寫入返回參數後函數返回前執行*//*3 defer語句反順序執行(棧)一般用於成對開啟、關閉、串連、中斷連線、加鎖、釋放鎖釋放資源*//*4 defer語句所在處變數入棧,只是函數結束再處理    該語句,若值傳遞則後續值改變不影響defer語句,    若地址傳遞則影響defer語句    defer函數參數在defer語句執行時初始化    defer函數調用時具體執行4.1 defer記錄函數的進入和退出,trace函數*//*5 方法為一種資料類型,方法定義後,通過賦值給具有方法的資料類型,則方法的類型與賦實值型別一致,可以執行方法操作*//*6 Each time a "defer" statement executes, the function valueand parameters to the call are evaluated as usualand saved anewbut the actual function is not invoked.anew: 重新再*//*7 defer函數調用函數傳回值與函數輸入參數按正常函數處理(複製新參數),閉包函數變數更新defer函數中變數更新,但實際函數沒有啟用。*//*8 函數返回的過程是這樣子的:先給傳回值賦值,然後調用defer運算式,最後才是返回到調用函數中。利用閉包defer函數(指標)可修改傳回值的值.*//*9 defer運算式可能會在設定函數傳回值之後,在返回到調用函數之前,修改傳回值,使最終的函數傳回值與你想象的不一致*//*10 defer+panic無panic的函數按defer正常執行: defer定義,func return/panic執行deferpanic 的函數僅執行panic之後語句不執行*///package mainimport (    "fmt"    "log"    "time")//定義方法type defMeth struct {    err bool    str string}//定義介面,介面為一種資料類型,提供操作type in interface {    ini()    prinOut()}func (def *defMeth) ini() {    def.err = true    def.str = "hei"}func (def *defMeth) prinOut() {    fmt.Println("just print: ", def)}type defError struct {    err error    str string}func (def *defError) ini() {    def.err = fmt.Errorf("this is an err: %s\n", "true")    def.str = "this is a bug"}func (def *defError) prinOut() {    fmt.Println("just print: ", def)}func main() {    var s1 defMeth    var s2 defError    var def in    a := 1    //defer+閉包處理, a為主函數變數,a值變化該defer函數變數會更新    defer func() { fmt.Println("close package, test the value of a:", a) }()    defer fmt.Println("fmt a is: ", a)    //值傳遞,defer函數入棧,變數值已賦值,只是最後執行    defer func(a int) { fmt.Println("no name func a is: ", a) }(a)    //地址傳遞:傳遞的為地址,若地址處值改變則操作值改變,map傳遞的地址    defer func(a *int) { fmt.Println("no name func a address is: ", *a) }(&a)    //為介面賦值變數類型及變數地址    def = &s1    //a:=1    def.ini()    //defer a=2 //錯誤defer後必須是函數或者方法或者介面    def.prinOut()    //fmt.Println("result", bigSlowOperation())    //介面    def = &s2    def.ini()    //函數中嵌套defer改變defer執行順序,函數中defer按棧執行,該函數正常執行    def.prinOut()    a++    fmt.Println(a)    fmt.Println("the value of bigSlow func: ", bigSlowOperation())    //10 test defer panic    deferPanic()}func bigSlowOperation() int {    log.Printf("main starts %s", "\n")    i := 1    //非匿名函數調用參數i已確定:1    //defer fmt.Println(i)    //匿名函數可調用傳回值:2    defer func() { fmt.Println(i) }()    defer trace("bigSlowOperation")() // don't forget the    //extra parentheses    // ...lots of work…    time.Sleep(10 * time.Second) // simulate slow operation    //by sleeping    i++    return i}//傳回值為函數,函數需要正常入棧,//函數輸入參數及返回地址按正常函數處理,//defer trace("")()//函數為trace中封裝的匿名函數,需正常處理該函數,//的形參及返回地址func trace(msg string) func() {    start := time.Now()    log.Printf("enter %s", msg)    return func() {        log.Printf("exit %s (%s)", msg, time.Since(start))    }}//10 defer+panic: what happends after a defer func panicfunc deferPanic() {    //正常執行    defer fmt.Println("the last defer panic func")    defer fmt.Println("the 3st defer panic func")    //panic func 僅執行panic語句    defer func() { panic("test defer panic"); fmt.Println("the func panics") }()    //正常執行    defer fmt.Println("the 2st defer panic func")    defer fmt.Println("the 1st defer panic func")}

 

75 次點擊  ∙  1 贊  
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.