關(guān)于 Golang defer 的使用規(guī)則和案例

golang defer 這個(gè)使用的執(zhí)行流程一直很繞,所以決定寫一篇文記錄一下。

規(guī)則一:當(dāng)defer被聲明時(shí),其參數(shù)就會(huì)被實(shí)時(shí)解析

案例一

package main

import (
    "fmt"
)

func main() {
    test()
}

func test() {
    defer f1(f2())

    fmt.Println("2")
    return
}

func f1(i int) int {
    return i
}

func f2() int {
    fmt.Println("1")
    return 1
}

輸出:12

案例二

package main

import (
    "fmt"
)

func main() {
    defer getFunc()()
    fmt.Println("2")
}

func getFunc() func() {
    fmt.Println("1")
    return func() {
        fmt.Println("3")
    }
}

輸出:123

注意區(qū)分傳入的是函數(shù)變量還是函數(shù)

1、函數(shù)變量

package main

import (
    "fmt"
)

func main() {
    defer f3(f2)
    fmt.Println("2")
}

func f2() int {
  fmt.Println("1")
  return 1
}

func f3(f func() int) int {
  return f()
}

輸出:21

2、函數(shù)

package main

import (
    "fmt"
)

func main() {
    defer f1(f2())
    fmt.Println("2")
}

func f1(i int) int {
  return i
}

func f2() int {
  fmt.Println("1")
  return 1
}

輸出:12

規(guī)則二:defer執(zhí)行順序?yàn)橄冗M(jìn)后出

package main

import (
    "fmt"
)

func main() {
    defer func() {
        fmt.Println("3")
    }()
    defer func() {
        fmt.Println("2")
    }()
    fmt.Println("1")
}

輸出:123

規(guī)則三:defer可以讀取有名返回值

func main() {
    i := 1
    defer func() {
        i++
        fmt.Println(i)
    }()
    fmt.Println(i)
}

輸出:12

所有規(guī)則復(fù)合體

package main

import (
    "fmt"
)

type msg struct {
    Num int
}

func (m *msg) print() {
    fmt.Println(m.Num)
}

func main() {
    m := new(msg)
    m.Num = 1
    defer m.print()
    defer func(m msg) {
        m.print()
    }(*m)
    m.Num = 2
}

輸出:12

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容