golang中如何使用推迟

  介绍

本篇文章给大家分享的是有关golang中如何使用推迟,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

在golang当中,推迟代码块会在函数调用链表中增加一个函数调用。这个函数调用不是普通的函数调用,而是会在函数正常返回,也就是返回之后添加一个函数调用。因此,推迟通常用来释放函数内部变量。

为了更好的学习推迟的行为,我们首先来看下面一段代码:

 func 拷贝文件(dstName, srcName 字符串),(written  int64, err 错误),{
  src, err :=, os.Open (srcName) if  err  !=, nil {返回}
  
  dst, err :=, os.Create (dstName) if  err  !=, nil {返回}
  
  写,err =, io.Copy (dst, src)
  dst.Close ()
  src.Close()返回}

这段代码可以运行,但存在& # 39;安全隐患& # 39;。如果调用dst,犯错:=os.Create (dstName)失败,则函数会执行返回退出运行。但之前创建的src(文件句柄)没有被释放。上面这段代码很简单,所以我们可以一眼看出存在文件未被释放的问题。如果我们的逻辑复杂或者代码调用过多时,这样的错误未必会被及时发现,而使用推迟则可以避免这种情况的发生,下面是使用延迟的代码:

 func 拷贝文件(dstName, srcName 字符串),(written  int64, err 错误),{
  src, err :=, os.Open (srcName) if  err  !=, nil {返回}defer  src.Close ()
  
  dst, err :=, os.Create (dstName) if  err  !=, nil {返回}defer  dst.Close () return  io.Copy (dst, src)
  }

通过推迟,我们可以在代码中优雅的关闭/清理代码中所使用的变量. def作为golang清理变量的特性,有其独有且明确的行为。以下是推迟三条使用规则。

规则一当推迟被声明时,其参数就会被实时解析

我们通过以下代码来解释这条规则:

 func 一个(),{小姐::=,0 defer  fmt.Println(我)
  我+ +
  返回
  }

上面我们说过,延期函数会在返回之后被调用。那么这段函数执行完之后,是不用应该输出1呢?

读者自行编译看一下,结果输出的是0。为什么?

这是因为虽然我们在延迟后面定义的是一个带变量的函数:fmt.Println(我)。但这个变量(i)在推迟被声明的时候,就已经确定其确定的值了,换言之,上面的代码等同于下面的代码:

 func 一个(),{
  小姐::=,0 defer  fmt.Println(0),//因为我=0,所以此时就明确告诉golang在程序退出时,执行输出0的操作我+ +返回}

为了更为明确的说明这个问题,我们继续定义一个推迟:

 func 一个(),{
  小姐::=,0 defer  fmt.Println (i),//输出0,因为我此时就是0 i++ defer  fmt.Println (i),//输出1,因为我此时就是1返回}

通过运行结果,可以看到推迟输出的值,就是定义时的值。<>强而不是推迟真正执行时的变量值(很重要,搞不清楚的话就会产生于预期不一致的结果)

但为什么是先输出1,在输出0呢?看下面的规则二。

规则二推迟执行顺序为先进后出

当同时定义了多个推迟代码块时,golang安装<强>先定义后执行强劲的顺序依次调用推迟。不要为什么,golang就是这么定义的。我们用下面的代码加深记忆和理解:

 func  b (), {for 小姐::=,0;,小姐:& lt;, 4,,我+ +,{defer  fmt.Print(我)
  }
  }

在循环中,依次定义了四个推迟代码块。结合规则一,我们可以明确得知每个推迟代码块应该输出什么值。安装先进后出的原则,我们可以看到依次输出了3210。

规则三推迟可以读取有名返回值

先看下面的代码:

 func  c(),(小姐:int), {defer  func (), {, i++} () return  1} 

输出结果是12。在开头的时候,我们说过延迟是在回调用之后才执行的。这里需要明确的是推迟代码块的作用域仍然在函数之内,结合上面的函数也就是说,推迟的作用域仍然在c函数之内。因此推迟仍然可以读取c函数内的变量(如果无法读取函数内变量,那又如何进行变量清除呢....)。

当执行返回1之后,我的值就是1。此时此刻,推迟代码块开始执行,对我进行自增操作,因此输出2。

掌握了推迟以上三条使用规则,那么当我们遇到推迟代码块时,就可以明确得知推迟的预期结果。

以上就是golang中如何使用推迟,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注行业资讯频道。

golang中如何使用推迟