Go语言defer语句的三种机制整理

Go语言中的defer语句用于在函数退出时执行一些操作,可以是函数调用、变量赋值等。defer语句的执行时机有三种机制,下面对这三种机制进行详细介绍。

1. 栈(Stack)机制

栈机制是defer语句最常见的执行机制。在函数中调用多个defer语句时,defer语句的执行顺序符合后进先出的栈结构规律。具体来说,当函数执行defer语句时,会把defer语句压入函数栈中,并在函数返回时按照LIFO(后进先出)的顺序依次执行这些defer语句。示例如下:

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

foo()

输出结果为:

foo
defer 2
defer 1

2. Copy机制

如果在函数中调用了一个期望语句无副作用的函数,为避免出现因为复制多次执行该函数而对程序产生影响的问题,Go语言使用copy机制来宏观地避免这种副作用的发生。也就是说,如果一个函数中调用了一个期望语句无副作用的函数,那么在函数返回时,会将该函数所产生的 defer 语句文本复制到一个新的位置,以确保每次执行该函数时,都是按照最近一次调用该函数时的defer语句顺序执行的。示例如下:

func demo() {
    fmt.Println("start")
    defer fmt.Println("defer 1")
    defer fmt.Println("defer 2")
    fmt.Println("end")
}

for i := 0; i < 3; i++ {
    demo()
}

输出结果为:

start
end
defer 2
defer 1
start
end
defer 2
defer 1
start
end
defer 2
defer 1

3. Return语句机制

在函数执行到return语句时,Go语言会进行两个步骤:首先,计算出所有的defer语句,按照栈的方式依次压入函数栈中,然后,执行函数的返回操作。在执行返回操作时,会按照常规顺序执行之前压入栈中defer语句。下面的示例代码演示了这种机制:

func deferDemo() (result int) {
    defer func() {
        result++
    }()
    return 0
}

fmt.Println(deferDemo()) // 输出 1

这个示例中,当函数执行到 return 0 语句时,展开的代码是 result=0; return。这时候会计算出defer语句result++,并将其压入函数栈中,然后执行函数返回操作,相当于执行result=0; result++;最后返回result的值为1。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Go语言defer语句的三种机制整理 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • elementui之封装下载模板和导入文件组件方式

    这里是关于 “elementui之封装下载模板和导入文件组件方式” 的完整攻略。 一、下载模板组件 对于 elementui,下载模板组件是一个十分常见的需求。我们可以使用 el-button 和 el-link 组件来实现。 首先,我们需要在组件中引入 Button 和 Link 组件。 import { Button, Link } from &quot…

    other 2023年6月25日
    00
  • upupoo无法使用怎么办 upupoo打不开解决方法攻略大全

    upupoo无法使用怎么办 upupoo打不开解决方法攻略大全 如果你在使用upupoo时遇到了无法使用或者打不开的情况,不要着急,下面我将为你提供一些可能的解决方法。 确认网络环境是否正常 首先,需要确认你的网络环境是否正常。请检查你的网络连接是否可用,确保你的设备已连接到可用的网络,并尝试使用其他网站或应用程序。 清除浏览器缓存和Cookie 如果网络环…

    other 2023年6月27日
    00
  • HTML5标签嵌套规则详解【必看】

    HTML5标签嵌套规则详解【必看】攻略 HTML5标签嵌套规则是指在HTML文档中,各个标签之间的嵌套关系必须符合一定的规则。这些规则有助于确保HTML文档的结构清晰、语义明确,并且能够正确地被浏览器解析和渲染。下面是HTML5标签嵌套规则的详细讲解。 1. 嵌套规则的基本原则 标签必须按照正确的层次结构进行嵌套,即一个标签可以包含其他标签,但不能交叉嵌套或…

    other 2023年7月27日
    00
  • web是什么意思?

    Web(全称World Wide Web)指的是万维网,是互联网的一部分,是一种基于超文本的、全球性的、公共的、互动的信息资源网络。Web是一种客户端/服务器模型的应用,通过HTTP协议从Web服务器获取HTML(超文本标记语言)文件,然后在客户端浏览器中解释并显示出来。 Web的起源可以追溯到1989年,由英国计算机科学家蒂姆·伯纳斯-李(Tim Bern…

    其他 2023年4月16日
    00
  • js继承的6种方式详解

    以下是js继承的六种方式的详细攻略。 1. 原型链继承 原型链继承是JavaScript中最基本的继承方式之一,它通过将父类的实例对象作为子类的原型对象来实现继承。这种方式的缺点是,所有子类实例对象共享同一个原型对象,当父类原型对象中的引用类型属性被修改时,所有子类实例对象中对应属性的值都会同时改变,这个缺点也被称之为“原型污染”问题。 示例代码如下: fu…

    other 2023年6月27日
    00
  • 关闭网站的wscript.shell命令行执行

    关闭网站的wscript.shell命令行执行指的是防止攻击者通过网站运行wscript.shell对象来执行任意命令,从而实施攻击的一种方法。以下是关闭网站wscript.shell命令行执行的完整攻略: 1. 禁止服务器上WScript.Shell对象的访问 在服务器上禁止WScript.Shell对象的访问是防止攻击者利用该对象执行任意命令的有效方法。…

    other 2023年6月26日
    00
  • layui加载数据显示loading加载完成loading消失的实例代码

    1. 基本思路 Layui提供了一个全局加载的效果,需要使用layer模块来实现。具体思路是:在数据加载之前显示loading图标,在数据加载完成之后隐藏loading图标。 2. 实现代码 下面是一个使用layui加载数据显示loading,完成后消失loading的实例代码: <!DOCTYPE html> <html> <…

    other 2023年6月25日
    00
  • 华为mate20 pro怎么卸载应用?华为mate20 pro删除应用程序教程

    以下是华为mate20 pro卸载应用的完整攻略,包含详细的步骤: 1. 打开应用管理器 在华为mate20 pro中,卸载应用的方法是通过应用管理器来进行的。因此,首先需要打开应用管理器。 你可以通过以下两种方法来打开应用管理器: 在主屏幕上,长按任何一个应用程序,等待出现应用选项,然后选择“应用管理器”。 或者,在主屏幕上,打开应用抽屉,找到并打开“设置…

    other 2023年6月25日
    00
合作推广
合作推广
分享本页
返回顶部