Golang学习笔记之延迟函数(defer)的使用小结
golang的defer优雅又简洁,是golang的亮点之一。defer在声明时不会立即执行,而是在函数return后,再按照先进后出的原则依次执行每个defer,一般用于释放资源、清理数据、记录日志、异常处理等。
关键字defer于注册延迟调用。这些调用直到ret前才被执行,通常用于释放资源或错误处理。
一、当defer被声明时,其参数就会被实时解析
funca(){ i:=0 deferfmt.Println(i)//输出0,因为i此时就是0 i++ deferfmt.Println(i)//输出1,因为i此时就是1 return }
二、当一个函数内多次调用defer时,Go会把defer调用放入到一个栈中,随后按照先进后出的顺序执行。
funcmain(){ deferfmt.Println("1") deferfmt.Println("2") deferfmt.Println("3") deferfmt.Println("4") }
输出顺序为4321
使用defer逆序输出字符串
name:="Naveen你好" fmt.Printf("%s\n",string(name)) fmt.Printf("逆序:") deferfmt.Printf("\n") for_,v:=range[]rune(name){ deferfmt.Printf("%c",v) }
输出:
Naveen你好
逆序:好你neevaN
三、defer的实际应用
func(rrect)area(wg*sync.WaitGroup){ ifr.length<0{ fmt.Printf("rect%v'slengthshouldbegreaterthanzero\n",r) wg.Done() return } ifr.width<0{ fmt.Printf("rect%v'swidthshouldbegreaterthanzero\n",r) wg.Done() return } area:=r.length*r.width fmt.Printf("rect%v'sarea%d\n",r,area) wg.Done() }
我们会发现上面wg.Done()被调用多次我们可以使用defer来优化代码
func(rrect)area(wg*sync.WaitGroup){ deferwg.Done() ifr.length<0{ fmt.Printf("rect%v'slengthshouldbegreaterthanzero\n",r) return } ifr.width<0{ fmt.Printf("rect%v'swidthshouldbegreaterthanzero\n",r) return } area:=r.length*r.width fmt.Printf("rect%v'sarea%d\n",r,area) }
使用defer延时调用,会在程序结束之前调用
下面举个例子:
packagemain import"fmt" funcdeferTest(numberint)int{ deferfunc(){ number++ fmt.Println("three:",number) }() deferfunc(){ number++ fmt.Println("two:",number) }() deferfunc(){ number++ fmt.Println("one:",number) }() returnnumber } funcmain(){ fmt.Println("函数返回值:",deferTest(0)) }
上面的代码打印的结果是:
one:1
two:2
three:3
函数返回值:0
PS:defer有一个重要的特性,即便函数抛出了异常,defer也会被执行的。这样就不会因为程序出现了错误,导致资源不会被释放了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。