zoukankan      html  css  js  c++  java
  • 2020-11-19:go中,defer原理是什么?

    福哥答案2020-11-19:
    - - 什么是defer
    - defer是go语言提供的一种用于注册延迟调用的机制:让函数或者语句在当前函数执行完毕(包括return正常结束或者panic导致的异常结束)之后执行。
    - defer语句通常用于一些成对的操作场景,打开/关闭连接,加锁/解锁,打开文件/关闭文件等等
    - defer在一些需要回收资源的场景中非常有用
    - 为什么需要defer
    - 有效防止内存泄漏
    - defer底层原理
    - 每次defer语句在执行的时候,都会将函数进行“压栈”,函数参数会被拷贝下来。当外层函数退出时,defer函数会按照定义的顺序逆序执行。如果defer执行的函数为nil,那么会在最终调用函数中产生panic。
    - 编译器会把 defer 语句翻译成对 deferproc 函数的调用,同时,编译器也会在使用了 defer 语句的 go 函数的末尾插入对 deferreturn 函数的调用。
    - 每一个goroutine结构体中都有一个_defer 指针变量用来存放defer单链表。defer保存用什么数据结构?回答栈过不了面试官那关,defer单链表应该能过关。_defer 结构体如下:
    - siz:所有传入参数的总大小。
    - started:该 defer 是否已经执行过。
    - heap:表明该defer是否存储在heap上。
    - sp:函数栈指针寄存器,一般指向当前函数栈的栈顶。
    - pc:程序计数器,有时称为指令指针(IP),线程利用它来跟踪下一个要执行的指令。在大多数处理器中,PC指向的是下一条指令,而不是当前指令。
    - fn:指向传入的函数地址和参数。
    - _panic:指向 _panic 链表。
    - link:指向 _defer 链表。
    - 为什么defer要按照定义的顺序逆序执行:后面定义的函数可能会依赖前面的资源,所以要先执行。如果前面先执行,释放掉这个依赖,那后面的函数就不能找到它的依赖了。
    - defer函数定义时,对外部变量的引用方式有两种,分别是函数参数以及作为闭包引用。在作为函数参数的时候,在defer定义时就把值传递给defer,并被cache起来。如果是作为闭包引用,则会在defer真正调用的时候,根据整个上下文云确定当前的值。
    - defer后面的语句在执行的时候,函数调用的参数会被保存起来,也就是复制一份。在真正执行的时候,实际上用到的是复制的变量,也就是说,如果这个变量是一个“值类型”,那他就和定义的时候是一致的,如果是一个“引用”,那么就可能和定义的时候的值不一致
    - 利用defer原理
    - 利用defer先求值,再延迟调用的性质
    - defer与return
    - defer语句的参数
    - defer语句表达式的值在定义的时候就已经确定了
    - 闭包:由函数以及相关引用环境组合而成的实例,也就是说闭包=函数+引用环境
    - 匿名函数:匿名函数就是我们说的闭包,它不能独立存在,但可以直接调用或者赋值于某个变量。一个闭包,继承了函数声明时的作用域。在go语言中,所有的匿名函数都是闭包
    - defer配合recover
    - recover:异常捕获,可以让程序在引发panic的时候不会崩溃退出。在引发panic的时候,panic会停掉当前正在执行的程序,但是,在这之前,它会有序的执行完当前goroutine的defer列表的语句。所以我们通常在defer里面挂一个recover,防止程序直接挂掉,类似于try...catch.recover()函数只在defer的上下文中才有效,直接调用,会返回nil
    ***
    [评论,有好几个参考地址](https://user.qzone.qq.com/3182319461/blog/1605740826)

  • 相关阅读:
    两个多项式的卷积【NTT】
    Determinant【矩阵的行列式的求法】
    2020 CCPC 长春题解
    Easy Equation【差分+前缀和】
    CF1433G-Reducing Delivery Cost【最短路】
    Interstellar Hunter【2020CCPC秦皇岛-I】
    P4721 【模板】分治 FFT
    关于Spring事务传播行为的个人见解
    InnoDB MVCC实现原理整理
    Nginx学习笔记(五、Nginx缓存与限流)
  • 原文地址:https://www.cnblogs.com/waitmoon/p/14008304.html
Copyright © 2011-2022 走看看