在 Go 中,確定請求是否已被取消可能是一個挑戰。考慮以下程式碼:
package main import ( "context" "log" "net/http" ) func main() { r, _ := http.NewRequest("GET", "http://example.com", nil) ctx, cancel := context.WithCancel(context.Background()) r = r.WithContext(ctx) ch := make(chan bool) go func() { _, err := http.DefaultClient.Do(r) log.Println(err == context.Canceled) ch <- true }() cancel() <-ch }
令人驚訝的是,即使請求應該被取消,此程式碼在 Go 1.9 中也會列印 false。
在更新的版本中在Go中,檢查取消的更好方法是使用Go 1.13中引入的errors.Is函數。這是程式碼的更新版本:
import ( "context" "errors" "log" "net/http" ) func main() { // Create a context that is already canceled ctx, cancel := context.WithCancel(context.Background()) cancel() // Create the request with it r, _ := http.NewRequestWithContext(ctx, "GET", "http://example.com", nil) // Do it, it will immediately fail because the context is canceled. _, err := http.DefaultClient.Do(r) log.Println(err) // Get http://example.com: context canceled // This prints false, because the http client wraps the context.Canceled // error into another one with extra information. log.Println(err == context.Canceled) // This prints true, because errors.Is checks all the errors in the wrap chain, // and returns true if any of them matches. log.Println(errors.Is(err, context.Canceled)) }
透過使用errors.Is,我們可以可靠地檢查底層錯誤是否是上下文取消錯誤,即使它已被另一個錯誤包裝。 error.Is 函數將遍歷整個錯誤鏈,如果其中任何一個與給定的錯誤類型匹配,則傳回 true。
以上是如何可靠地檢查 Go 中的請求取消錯誤,即使它已被另一個錯誤包裹?的詳細內容。更多資訊請關注PHP中文網其他相關文章!