亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

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

為什么當 annoymouse 函數返回時 defer 語句的工作方式不同

為什么當 annoymouse 函數返回時 defer 語句的工作方式不同

Go
慕哥9229398 2023-08-07 14:54:06
這里我聲明了一個推遲trace1的函數func TestDeferFunc(t *testing.T) {    fmt.Println("start", time.Now())    defer trace1()    time.Sleep(3 * time.Second)}func trace1() {    startTime := time.Now()    fmt.Println("end time: ", startTime)    fmt.Println("execute time: ", time.Since(startTime))}運行后go test -run=^TestDeferFunc$,下面是我得到的start 2019-11-26 12:50:59.59489797 +0800 CST m=+0.000202866end time:  2019-11-26 12:51:02.595090951 +0800 CST m=+3.000395880execute time:  49.065μs然而,當我推遲另一個 annoymouse 函數時,事情發生了變化func TestDeferFunc(t *testing.T) {    fmt.Println("start", time.Now())    defer trace2()()    time.Sleep(3 * time.Second)}func trace2() func() {    startTime := time.Now()    fmt.Println("end time: ", startTime)    fmt.Println("execute time: ", time.Since(startTime))    return func() {        fmt.Println("zzz")    }}下面是go test結果start 2019-11-26 12:52:58.318472958 +0800 CST m=+0.000197852end time:  2019-11-26 12:52:58.318554368 +0800 CST m=+0.000279262execute time:  4.853μszzz有人可以幫我嗎!謝謝
查看完整描述

2 回答

?
三國紛爭

TA貢獻1804條經驗 獲得超7個贊

這是因為defer語句僅defer評估函數調用 - 并且函數調用在defer執行時評估。根據文檔:

每次執行“defer”語句時,調用的函數值和參數都會照常評估并重新保存,但不會調用實際函數。相反,延遲函數會在周圍函數返回之前立即調用,調用順序與延遲函數相反。也就是說,如果周圍函數通過顯式 return 語句返回,則延遲函數將在該 return 語句設置任何結果參數之后但在函數返回到其調用者之前執行。如果延遲函數值求值為 nil,則在調用該函數時(而不是執行“defer”語句時)會發生執行混亂。

您的代碼defer trace2()()本質上相當于f := trace2(); defer f(). 因此trace2立即被評估(并因此被調用)。

因此,為了實現您可能想要的(跟蹤時間),您可以像這樣defer trace3()()使用:trace3()

func trace3() func() {

    startTime := time.Now()


    return func() {

        fmt.Println("end time: ", time.Now())

        fmt.Println("execute time: ", time.Since(startTime))

    }

}


查看完整回答
反對 回復 2023-08-07
?
哆啦的時光機

TA貢獻1779條經驗 獲得超6個贊

使用 defer 跟蹤時間的方法是將開始時間傳遞給 deferred 函數:


func trace1(startTime time.Time) {

    fmt.Println("start", startTime)

    fmt.Println("end time: ", time.Now())

    fmt.Println("execute time: ", time.Since(startTime))

}


func TestDeferFunc(t *testing.T) {

    defer trace1(time.Now())

    time.Sleep(3 * time.Second)

}

傳遞的參數會立即執行,但實際的函數調用會推遲到最后。


如果您想更明確地了解執行的內容和延遲的內容,可以將整個內容包裝在一個函數中,以便確保內部的所有內容都在最后執行


defer func() {

    ..... code ....

}()


查看完整回答
反對 回復 2023-08-07
  • 2 回答
  • 0 關注
  • 141 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號