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

DukeAnn · · 678 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

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


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:DukeAnn

查看原文:关于 Golang defer 的使用规则和案例

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

678 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传