第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

當(dāng) defer 在同一個變量上被調(diào)用兩次時會發(fā)生什么?

當(dāng) defer 在同一個變量上被調(diào)用兩次時會發(fā)生什么?

Go
Qyouu 2021-09-20 10:59:07
當(dāng)該方法的結(jié)構(gòu)已更改時,兩次調(diào)用 defer 會發(fā)生什么?例如:rows := Query(`SELECT FROM whatever`)defer rows.Close()for rows.Next() {   // do something}rows = Query(`SELECT FROM another`) defer rows.Close()for rows.Next() {  // do something else}哪個rows時候上次rows.Close()打電話?
查看完整描述

3 回答

?
qq_花開花謝_0

TA貢獻(xiàn)1835條經(jīng)驗 獲得超7個贊

這取決于方法接收者和變量的類型。


簡短回答:如果您正在使用該database/sql包,您的延遲Rows.Close()方法將正確關(guān)閉您的兩個Rows實例,因為Rows.Close()有指針接收器并且因為DB.Query()返回一個指針(rows也是一個指針)。請參閱下面的推理和解釋。


為避免混淆,我建議使用不同的變量,并且很清楚您想要什么以及將關(guān)閉什么:


rows := Query(`SELECT FROM whatever`)

defer rows.Close()

// ...

rows2 := Query(`SELECT FROM whatever`)

defer rows2.Close()

我想指出一個重要的事實,它來自延遲函數(shù)及其參數(shù)被立即評估,這在Effective Go博客文章和語言規(guī)范:延遲語句中也有說明:


每次執(zhí)行“defer”語句時,函數(shù)值和調(diào)用的參數(shù)都會像往常一樣評估并重新保存,但不會調(diào)用實際的函數(shù)。相反,在周圍函數(shù)返回之前立即調(diào)用延遲函數(shù),以與延遲相反的順序調(diào)用。


如果變量不是指針:當(dāng)調(diào)用延遲的方法時,您將觀察到不同的結(jié)果,這取決于該方法是否具有指針接收器。

如果變量是一個指針,您將始終看到“期望”的結(jié)果。


看這個例子:


type X struct {

    S string

}


func (x X) Close() {

    fmt.Println("Value-Closing", x.S)

}


func (x *X) CloseP() {

    fmt.Println("Pointer-Closing", x.S)

}


func main() {

    x := X{"Value-X First"}

    defer x.Close()

    x = X{"Value-X Second"}

    defer x.Close()


    x2 := X{"Value-X2 First"}

    defer x2.CloseP()

    x2 = X{"Value-X2 Second"}

    defer x2.CloseP()


    xp := &X{"Pointer-X First"}

    defer xp.Close()

    xp = &X{"Pointer-X Second"}

    defer xp.Close()


    xp2 := &X{"Pointer-X2 First"}

    defer xp2.CloseP()

    xp2 = &X{"Pointer-X2 Second"}

    defer xp2.CloseP()

}

輸出:


Pointer-Closing Pointer-X2 Second

Pointer-Closing Pointer-X2 First

Value-Closing Pointer-X Second

Value-Closing Pointer-X First

Pointer-Closing Value-X2 Second

Pointer-Closing Value-X2 Second

Value-Closing Value-X Second

Value-Closing Value-X First

在Go Playground上試一試。


使用指針變量的結(jié)果總是好的(如預(yù)期的那樣)。


使用非指針變量和指針接收器,我們會看到相同的打印結(jié)果(最新的),但如果我們有值接收器,它會打印 2 個不同的結(jié)果。


非指針變量說明:


如前所述,包括接收器在內(nèi)的延遲函數(shù)在defer執(zhí)行時被評估。如果是指針接收器,它將是局部變量的地址。因此,當(dāng)您為其分配一個新值并調(diào)用 another 時defer,指針接收器將再次使用本地變量的相同地址(只是指向的值不同)。所以稍后在執(zhí)行函數(shù)時,兩者都會使用相同的地址兩次,但指向的值將相同,即稍后分配的值。


在值接收器的情況下,接收器是執(zhí)行時創(chuàng)建的副本defer,因此如果您為變量分配一個新值并調(diào)用 another defer,則會創(chuàng)建另一個與前一個不同的副本。


查看完整回答
反對 回復(fù) 2021-09-20
?
猛跑小豬

TA貢獻(xiàn)1858條經(jīng)驗 獲得超8個贊

有效的圍棋提到:

延遲函數(shù)的參數(shù)(如果函數(shù)是方法,則包括接收者)在延遲執(zhí)行時計算,而不是在調(diào)用執(zhí)行時計算。

除了避免擔(dān)心函數(shù)執(zhí)行時變量會改變值,這意味著單個延遲調(diào)用站點可以延遲多個函數(shù)執(zhí)行

在您的情況下,延遲將引用第二行實例。
這兩個延遲函數(shù)以 LIFO 順序執(zhí)行(也如“延遲、恐慌和恢復(fù)”中所述)。

正如icza在他的回答和評論中提到的:

2 個延遲Close()方法將引用2 個不同的 Rows 值,并且兩者都將被正確關(guān)閉,因為rows指針,而不是值類型。


查看完整回答
反對 回復(fù) 2021-09-20
  • 3 回答
  • 0 關(guān)注
  • 315 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號