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

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. idea自动下载依赖的源代码等信息

    mvn dependency:sources -DdownloadSources=true -DdownloadJavadocs=true

  2. AWS 存储服务(三)

    目录 AWS S3 业务场景 挑战 解决方案 S3的好处 S3 属性 存储桶 Buckets 对象 Object S3 特性 S3 操作 可用性和持久性 一致性 S3 定价策略 S3高级功能 存储级别 ...

  3. OpenCV计算机视觉实战(Python版)资源

    疲劳检测 pan.baidu.com/s/1Ng_-utB8BSrXlgVelc8ovw #导入工具包 from scipy.spatial import distance as dist from ...

  4. hdu 1106

    排序 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submissi ...

  5. jqGrid全部选中

    var jqGrid = $("#jqGrid"); // 拿到所有行id var jqGridIDs = jqGrid.getDataIDs(); // 拿到所有选中行id va ...

  6. LeetCode 题目的 Python 实现(持续更新中)

    Python-LeetCode 是一个使用 Python 语言解决 LeetCode 问题的代码库,库有以下几个方面需要注意: 所有题目都是 AC 的: 按照题目顺序,每 50 个放在一个目录下,方便 ...

  7. Hystrix(下),使用公共降级类

    使用Hystrix熔断(下) 在一个分布式系统里,一个服务依赖多个服务,可能存在某个服务调用失败,         比如超时.异常等,如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败,   ...

  8. pandas数据结构之基础运算笔记

    import pandas as pd import numpy as np s = pd.Series([1,3,5,6,8],index=list('acefh')) s.index # 读取行索 ...

  9. c++学习---迭代器

    迭代器类型: begin和end的返回值的类型由对象是否为常量所决定 无论对象是都为常量,cbegin和cend都将都到一个const_iterator

  10. Hibernate一对多自关联、多对多关联

    今天分享hibernate框架的两个关联关系    多对多关系注意事项 一定要定义一个主控方 多对多删除 主控方直接删除 被控方先通过主控方解除多对多关系,再删除被控方 禁用级联删除 关联关系编辑,不 ...