可以用作一些资源的释放。

1.在一个函数内的defer执行顺序是先写的后执行,后写的先执行(遵循栈结构)

func DeferTest1(){
defer fmt.Println("我是 defer1")
defer fmt.Println("我是 defer2")
fmt.Println("我是DeferTest1")
fmt.Println("我是DeferTest2")
}

结果:

我是DeferTest1
我是DeferTest2
我是 defer2
我是 defer1 

2.defer 执行语句的值和定义defer语句函数的关系

func DeferTest2(){
i:= 0
defer fmt.Printf("defer i=%d\t",i)
for ;i<=10;i++{
fmt.Printf("i=%d\t",i)
}
fmt.Println()
}

执行结果

i=0	i=1	i=2	i=3	i=4	i=5	i=6	i=7	i=8	i=9	i=10
defer i=0

3.defer的原理

首先看下defer和return语句的区别,如下

可以看到 return 执行的时候 将结果x赋值给了返回值,然后执行了RET指令,而defer语句执行的时候,是在RET指令之前。所以这里注意一下。返回值和x的关系。如果x是一个值类型,这里是进行了拷贝的。可以看下下面几个例子:

func defer1() int {
  x := 1
  defer func() {
   x++
  }()
  return x
} 

func defer2() (x int) {
  defer func() {
    x++
  }()
  return 1
} 

func defer3() (y int) {
  x := 1
  defer func() {
    x++
  }()
  return x
} 

func defer4() (x int) {
  defer func(x int) {
    x++
}(x)
return 1
} 

分别打印这几个方法的结果,返回值分别如下:

defer1: 1
defer2: 2
defer3: 1
defer4: 1

根据上面图上的解释:

①defer执行之前,将x赋值给了返回值(这是一个值拷贝),然后修改x的值,对返回值是无影响的,所以返回的是1

②返回值的名称就是x,此时defer执行前把x赋值为1,然后defer修改x的值, x被增加,故返回的是2

③返回值名称是y,defer执行前,y被赋值为1,defer执行修改x对y无影响,返回也是1

④返回值名称虽然是x,但是defer执行的func是一个带参数的函数,此时传入的参数x是一个值拷贝,作用域是内部,对于外部的x无影响,所以返回的也是1

Go语言中的defer的更多相关文章

  1. C语言中,头文件和源文件的关系(转)

    简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成纯汇编语句, ...

  2. C 语言中 setjmp 和 longjmp

    在 C 语言中,我们不能使用 goto 语句来跳转到另一个函数中的某个 label 处:但提供了两个函数——setjmp 和 longjmp来完成这种类型的分支跳转.后面我们会看到这两个函数在处理异常 ...

  3. c语言中的scanf在java中应该怎么表达,Scanner类。

    1 java是面向对象的语言 它没有像C语言中的scanf()函数,但是它的类库中有含有scanf功能的函数 2 java.util包下有Scanner类 Scanner类的功能与scanf类似 3 ...

  4. C语言中do...while(0)的妙用(转载)

    转载来自:C语言中do...while(0)的妙用,感谢分享. 在linux内核代码中,经常看到do...while(0)的宏,do...while(0)有很多作用,下面举出几个: 1.避免goto语 ...

  5. C语言中,定义的含义?声明的含义?它们之间的区别是什么?

    在C语言中,对于定义和声明,也许我们非常的熟悉,但不一定真正的了解! 定义的含义:所谓定义,就是创建(编译器)一个对象,为这个对象分配一块内存空间并取名,也就是我们平常所说的变量名或对象名,一旦这个名 ...

  6. C++中函数的默认参数和C语言中volatile的学习

    1.函数默认参数 1 int func(int a,int b=10) 2 { 3 return a*b; 4 } 5 6 int main() 7 { 8 int c=func(2); 9 cout ...

  7. C语言中qsort函数用法

    C语言中qsort函数用法-示例分析    本文实例汇总介绍了C语言中qsort函数用法,包括针对各种数据类型参数的排序,非常具有实用价值非常具有实用价值. 分享给大家供大家参考.C语言中的qsort ...

  8. c语言中time相关函数

    工作中遇到的函数: int seed = time(NULL); srand(seed); signal(SIGINT, stop); signal(SIGUSR1, sig_usr1); 搜time ...

  9. C语言中的static 详细分析

    转自:http://blog.csdn.net/keyeagle/article/details/6708077/ google了近三页的关于C语言中static的内容,发现可用的信息很少,要么长篇大 ...

随机推荐

  1. Azure DevOps 利用rest api设置variable group

    我们在Azure DevOps中设置参数的时候,可以使用build,release各自的variables,但是各自的变量不能共用.此时我们需要使用variable group,它允许跨Build和R ...

  2. 通过命令行给 XenServer 打补丁

    安装 XenCenter 客户端,cmd 到 XenCenter 安装目录. 1.上传补丁到服务器,获得uuid xe patch-upload -s <服务器IP地址> -u root ...

  3. 【计算机视觉】Object Proposal之BING++

    本文是对 BING 算法的升级,主要是在快的同时保持定位精度  两个 + 分别对应: edge-based recursive boxes as one "+", and MTSE ...

  4. [转帖]Linux中awk工具的使用

    Linux中awk工具的使用 2018年10月09日 17:26:20 谢公子 阅读数 2170更多 分类专栏: linux系统安全   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权 ...

  5. JDBC 注册驱动,获取连接

    jdbc 动力节点视频教程 JDBC编程六步 1.注册驱动(作用:告诉Java程序,即将要连接的是哪个品牌的数据库) 2.获取连接 (表示JVM进程和数据库进程之间的通道打开了,属于进程间的通信,重量 ...

  6. 正则与re模块

    一.正则表达式 在线测试工具 http://tool.chinaz.com/regex/ 1.字符组 ​ 在同一个位置可能出现的各种字符组成一个字符组,在正则表达中用[ ]表示 ​ 一个正则就是一条匹 ...

  7. js — 基础知识

    目录 1. js的介绍 2. js的引入方式 3. js语句 4. 变量 js ( Javascript ) - 脚本语言 1. js的介绍 Javascript是一种运行在浏览器中的解释型的编程语言 ...

  8. hdu 6197 array array array LIS

    正反跑一次LIS,取最大的长度,如果长度大于n-k就满足条件. ac代码: #include <cstdio> #include <cstring> #include < ...

  9. (一)JMS简介

    一.简介 JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进 ...

  10. AES密码算法详解(转自https://www.cnblogs.com/luop/p/4334160.html)

    0 AES简介 我们知道数据加密标准(Data Encryption Standard: DES)的密钥长度是56比特,因此算法的理论安全强度是256.但二十世纪中后期正是计算机飞速发展的阶段,元器件 ...