Golang學(xué)習(xí)筆記之延遲函數(shù)(defer)的使用小結(jié)
golang的defer優(yōu)雅又簡(jiǎn)潔, 是golang的亮點(diǎn)之一。defer在聲明時(shí)不會(huì)立即執(zhí)行,而是在函數(shù)return后,再按照先進(jìn)后出的原則依次執(zhí)行每個(gè)defer,一般用于釋放資源、清理數(shù)據(jù)、記錄日志、異常處理等。
關(guān)鍵字defer于注冊(cè)延遲調(diào)用。這些調(diào)用直到 ret 前才被執(zhí)行,通常用于釋放資源或錯(cuò)誤處理。
一、當(dāng)defer被聲明時(shí),其參數(shù)就會(huì)被實(shí)時(shí)解析
func a() { i := 0 defer fmt.Println(i) //輸出0,因?yàn)閕此時(shí)就是0 i++ defer fmt.Println(i) //輸出1,因?yàn)閕此時(shí)就是1 return }
二、當(dāng)一個(gè)函數(shù)內(nèi)多次調(diào)用 defer 時(shí),Go 會(huì)把 defer 調(diào)用放入到一個(gè)棧中,隨后按照先進(jìn)后出的順序執(zhí)行。
func main() { defer fmt.Println("1") defer fmt.Println("2") defer fmt.Println("3") defer fmt.Println("4") }
輸出順序?yàn)?321
使用defer逆序輸出字符串
name := "Naveen你好" fmt.Printf("%s\n", string(name)) fmt.Printf("逆序:") defer fmt.Printf("\n") for _, v := range []rune(name) { defer fmt.Printf("%c", v) }
輸出:
Naveen你好
逆序:好你neevaN
三、defer 的實(shí)際應(yīng)用
func (r rect) area(wg *sync.WaitGroup) { if r.length < 0 { fmt.Printf("rect %v's length should be greater than zero\n", r) wg.Done() return } if r.width < 0 { fmt.Printf("rect %v's width should be greater than zero\n", r) wg.Done() return } area := r.length * r.width fmt.Printf("rect %v's area %d\n", r, area) wg.Done() }
我們會(huì)發(fā)現(xiàn)上面wg.Done()被調(diào)用多次我們可以使用defer來優(yōu)化代碼
func (r rect) area(wg *sync.WaitGroup) { defer wg.Done() if r.length < 0 { fmt.Printf("rect %v's length should be greater than zero\n", r) return } if r.width < 0 { fmt.Printf("rect %v's width should be greater than zero\n", r) return } area := r.length * r.width fmt.Printf("rect %v's area %d\n", r, area) }
使用defer延時(shí)調(diào)用,會(huì)在程序結(jié)束之前調(diào)用
下面舉個(gè)例子:
package main import "fmt" func deferTest(number int) int { defer func() { number++ fmt.Println("three:", number) }() defer func() { number++ fmt.Println("two:", number) }() defer func() { number++ fmt.Println("one:", number) }() return number } func main() { fmt.Println("函數(shù)返回值:", deferTest(0)) }
上面的代碼打印的結(jié)果是:
one: 1
two: 2
three: 3
函數(shù)返回值: 0
PS:defer 有一個(gè)重要的特性,即便函數(shù)拋出了異常,defer也會(huì)被執(zhí)行的。這樣就不會(huì)因?yàn)槌绦虺霈F(xiàn)了錯(cuò)誤,導(dǎo)致資源不會(huì)被釋放了。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
golang-gin-mgo高并發(fā)服務(wù)器搭建教程
這篇文章主要介紹了golang-gin-mgo高并發(fā)服務(wù)器搭建教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-12-12golang 檢查網(wǎng)絡(luò)狀態(tài)是否正常的方法
今天小編就為大家分享一篇golang 檢查網(wǎng)絡(luò)狀態(tài)是否正常的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-07-07探索Golang實(shí)現(xiàn)Redis持久化AOF實(shí)例
這篇文章主要為大家介紹了Golang實(shí)現(xiàn)Redis持久化AOF實(shí)例探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01Go 庫(kù)bytes.Buffer和strings.Builder使用及性能對(duì)比
這篇文章主要為大家介紹了Go 庫(kù)bytes.Buffer和strings.Builder使用及性能對(duì)比,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12Go語(yǔ)言擴(kuò)展原語(yǔ)之ErrGroup的用法詳解
除標(biāo)準(zhǔn)庫(kù)中提供的同步原語(yǔ)外,Go語(yǔ)言還在子倉(cāng)庫(kù)sync中提供了4種擴(kuò)展原語(yǔ),本文主要為大家介紹的是其中的golang/sync/errgroup.Group,感興趣的小伙伴可以了解一下2023-07-07提升Go語(yǔ)言開發(fā)效率的小技巧實(shí)例(GO語(yǔ)言語(yǔ)法糖)匯總
這篇文章主要介紹了提升Go語(yǔ)言開發(fā)效率的小技巧匯總,也就是Go語(yǔ)言的語(yǔ)法糖,掌握好這些可以提高我們的開發(fā)效率,需要的朋友可以參考下2022-11-11