Golang关键字defer的用法详解.docx

  1. 1、本文档共8页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多

Golang关键字defer的用法详解

目录1.defer的简单介绍与使用场景2.defer在return执行的时机3.小结

1.defer的简单介绍与使用场景

defer是Go里面的一个关键字,用在方法或函数前面,作为方法或函数的延迟调用。它主要用于以下两个场景:

优雅释放资源,比如一些网络连接、数据库连接以及文件资源的释放。与recover配合处理panic异常

场景一:复制文件

funcCopyFile(dstFile,srcFilestring)(wrint64,errerror){

src,err:=os.Open(srcFile)

iferr!=nil{

return

dst,err:=os.Create(dstFile)

iferr!=nil{

return

wr,err=io.Copy(dst,src)

dst.Close()

src.Close()

return

}

这样的代码是有问题的,当第6行执行失败的时候程序返回但没有关闭前面成功打开的src,资源没有正确关闭,正确代码如下:

(在成功打开资源,没返回err的情况下,都可以使用defer进行优雅的关闭资源)

funcCopyFile(dstFile,srcFilestring)(wrint64,errerror){

src,err:=os.Open(srcFile)

iferr!=nil{

return

defersrc.Close()

dst,err:=os.Create(dstFile)

iferr!=nil{

return

deferdst.Close()

wr,err=io.Copy(dst,src)

returnerr

}

场景二:处理异常panic

packagemain

importfmt

funcmain(){

deferfunc(){

ifr:=recover();r!=nil{

fmt.Println(r)

a:=1

b:=0

fmt.Println(result:,a/b)

}

运行结果:

runtimeerror:integerdividebyzero

程序没有输出result,会抛出panic,因为不能对除数为0的数做除法,我们使用defer在程序发生panic的时候捕获异常。go中是用panic抛异常,recover捕获异常,异常会在下一篇go文章进行分析。

通过这两个使用场景我们也可以看到defer后面跟着的函数被调用的时间:

函数return的时候当前协程发生panic的时候

说到延迟函数被调用的时机,这时顺便说一下多个延迟函数被调用时候的执行顺序问题。官方对defer的解释中写到每次defer语句执行的时候,会把函数压栈,同时函数参数会被拷贝下来

这两点很重要:

一是说明当一个函数中有多个defer的时候,执行顺序是LIFO先进后出

二是说明延迟函数的参数在defer语句出现时就已经确定下来了

这段代码是用来补充这二点的:看一下能否看懂执行结果,能的话就直接跳到第二部分

funcdeferRun1(){

varnum=1

numptr:=num

deferfmt.Println(deferrun1:\n,numptr,num,*numptr)//0xc00002208811

deferfunc(){

fmt.Println(deferrun2:\n,numptr,num,*numptr)//0xc00011602822

deferfunc(numint,numptr*int){

fmt.Println(deferrun3:\n,numptr,num,*numptr)//0xc00011602812

}(num,numptr)

num=2

fmt.Println(numptr,num,*numptr)//0xc00011602822

return

}

对于第一个defer,传入的num和*numptr都是一个具体的值,所以程序return完之后结果会是1,1

对于第二个d

文档评论(0)

135****8957 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档