GO語言的Context

context包定義了 Context 接口,Context 的具體實現包括 4 個方法,分別是Deadline、Done、Err 和 Value,如下所示:
下面來具體解釋下這 4 個方法。
 
Deadline 方法會返回這個 Context 被取消的截止日期。如果沒有設置截止日期,ok 的值是 false。後續每次調用這個對象的 Deadline 方法時,都會返回和第一次調用相同的結果。
 
Done 方法返回一個 Channel 對象。在 Context 被取消時,此 Channel 會被 close,如果沒被取消,可能會返回 nil。後續的 Done 調用總是返回相同的結果。當 Done 被 close的時候,你可以通過 ctx.Err 獲取錯誤信息。Done 這個方法名其實起得並不好,因爲名字太過籠統,不能明確反映 Done 被 close 的原因,因爲 cancel、timeout、deadline 都可能導致 Done 被 close,不過,目前還沒有一個更合適的方法名稱。
 
關於 Done 方法,你必須要記住的知識點就是:如果 Done 沒有被 close,Err 方法返回nil;如果 Done 被 close,Err 方法會返回 Done 被 close 的原因。
 
Value 返回此 ctx 中和指定的 key 相關聯的 value。
 
Context 中實現了 2 個常用的生成頂層 Context 的方法。
context.Background():返回一個非 nil 的、空的 Context,沒有任何值,不會被cancel,不會超時,沒有截止日期。一般用在主函數、初始化、測試以及創建根Context 的時候。
context.TODO():返回一個非 nil 的、空的 Context,沒有任何值,不會被 cancel,不會超時,沒有截止日期。當你不清楚是否該用 Context,或者目前還不知道要傳遞一些什麼上下文信息的時候,就可以使用這個方法。
官方文檔是這麼講的,你可能會覺得像沒說一樣,因爲界限並不是很明顯。其實,你根本不用費腦子去考慮,可以直接使用 context.Background。事實上,它們兩個底層的實現是一模一樣的:

 

 

在使用 Context 的時候,有一些約定俗成的規則。
1. 一般函數使用 Context 的時候,會把這個參數放在第一個參數的位置。從來不把 nil 當做 Context 類型的參數值,可以使用 context.Background() 創建一個空的上下文對象,也不要使用 nil。
2.Context 只用來臨時做函數之間的上下文透傳,不能持久化 Context 或者把 Context長久保存。把 Context 持久化到數據庫、本地文件或者全局變量、緩存中都是錯誤的用法。
3.key 的類型不應該是字符串類型或者其它內建類型,否則容易在包之間使用 Context 時候產生衝突。使用 WithValue 時,key 的類型應該是自己定義的類型。
4.常常使用 struct{}作爲底層類型定義 key 的類型。對於 exported key 的靜態類型,常常是接口或者指針。這樣可以儘量減少內存分配。 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章