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

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

延遲函數(shù)執(zhí)行順序

延遲函數(shù)執(zhí)行順序

Go
守著星空守著你 2022-10-10 17:55:00
我正在學(xué)習(xí) golang 源代碼并陷入延遲函數(shù)執(zhí)行順序。我有兩個(gè)文件:一個(gè)定義端點(diǎn)的行為,另一個(gè)用于測(cè)試。我刪除了一些與我的問題無(wú)關(guān)的代碼以減少閱讀的行數(shù)。端點(diǎn)定義文件// Endpoint is the fundamental building block of servers and clients.// It represents a single RPC method.type Endpoint func(ctx context.Context, request interface{}) (response interface{}, err error)// Middleware is a chainable behavior modifier for endpoints.type Middleware func(Endpoint) Endpoint// Chain is a helper function for composing middlewares. Requests will// traverse them in the order they're declared. That is, the first middleware// is treated as the outermost middleware.func Chain(outer Middleware, others ...Middleware) Middleware {    return func(next Endpoint) Endpoint {        for i := len(others) - 1; i >= 0; i-- { // reverse            next = others[i](next)        }        return outer(next)    }}測(cè)試文件包含打印的步驟。func ExampleChain() {    e := endpoint.Chain(        annotate("first"),        annotate("second"),        annotate("third"),    )(myEndpoint)    if _, err := e(ctx, req); err != nil {        panic(err)    }    // Output:    // first pre    // second pre    // third pre    // my endpoint!    // third post    // second post    // first post}var (    ctx = context.Background()    req = struct{}{})據(jù)我了解,這三個(gè)annotate方法應(yīng)該先執(zhí)行,然后endpoint.Chain方法,myEndpoint最后執(zhí)行。此外,由于pre首先打印,并且當(dāng)函數(shù)返回“post”時(shí),應(yīng)該按照defergo doc 中的說(shuō)明進(jìn)行操作: A "defer" statement invokes a function whose execution is deferred to the moment the surrounding function returns, either because the surrounding function executed a return statement, reached the end of its function body, or because the corresponding goroutine is panicking.所以我期望看到的是    // Output:    // first pre    // first post    // second pre    // second post    // third pre    // third post    // my endpoint!簡(jiǎn)而言之,我的問題是:為什么first pre后面不跟first post,一樣second third。s的順序post顛倒了。endpoint.Chain反向執(zhí)行返回值列表但annotate首先annotate評(píng)估方法對(duì)嗎?不是說(shuō),pres 被打印,這意味著首先執(zhí)行內(nèi)部函數(shù)
查看完整描述

2 回答

?
小怪獸愛吃肉

TA貢獻(xiàn)1852條經(jīng)驗(yàn) 獲得超1個(gè)贊

延遲函數(shù)作為函數(shù)中的最后一件事運(yùn)行,在 return 語(yǔ)句之后,所以annotate函數(shù)將首先運(yùn)行next,只有在返回之后,延遲函數(shù)才會(huì)運(yùn)行。根據(jù)您的代碼,它應(yīng)該打印的順序是:


first pre

second pre

third pre

my endpoint

third post

second post

first post


查看完整回答
反對(duì) 回復(fù) 2022-10-10
?
阿晨1998

TA貢獻(xiàn)2037條經(jīng)驗(yàn) 獲得超6個(gè)贊

這是您的示例變成了在 Go 操場(chǎng)上運(yùn)行的東西。

請(qǐng)注意,如果您在給定函數(shù)中defer 多次調(diào)用,則每個(gè)延遲調(diào)用都按 LIFO 順序運(yùn)行。因此,如果您想使用defer確保您post首先被調(diào)用,然后是next操作,請(qǐng)考慮替換:


defer fmt.Println(s, "post")

next(ctx, request)

和:


defer next(ctx, request)

defer fmt.Println(s, "post)

當(dāng)然,在您的情況下,您想返回什么next返回,這會(huì)產(chǎn)生一個(gè)小問題。要在實(shí)際情況下解決這個(gè)問題,您需要一個(gè)小函數(shù)和一些命名的返回值:


defer func() { i, e = next(ctx, request) }()

其中i和e是命名的返回值。


這是相同的代碼變成了一個(gè)新示例,其中延遲調(diào)用以所需的順序發(fā)生。 在這種情況下,這個(gè)例子是相當(dāng)愚蠢的,因?yàn)闆]有任何恐慌,也沒有中間的“危險(xiǎn)步驟”,所以我們真正需要的是fmt.Println按順序執(zhí)行這兩個(gè)調(diào)用,而不使用defer. 但是,如果我們可以在the和 post 部分之間感到恐慌fmt.Println(s, "pre"),那么這可能是有道理的。



查看完整回答
反對(duì) 回復(fù) 2022-10-10
  • 2 回答
  • 0 關(guān)注
  • 119 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號(hào)

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