关于 Golang defer 的使用规则和案例

golang defer 这个使用的执行流程一直很绕,所以决定写一篇文记录一下。

规则一:当defer被声明时,其参数就会被实时解析

案例一

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

注意区分传入的是函数变量还是函数

1、函数变量

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、函数

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

规则二:defer执行顺序为先进后出

package main

import (
    "fmt"
)

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

输出:123

规则三:defer可以读取有名返回值

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

输出:12

所有规则复合体

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

本作品采用《CC 协议》,转载必须注明作者和本文链接
做自己
讨论数量: 1
ZsmHub

学习了

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!