您好,登錄后才能下訂單哦!
Go中Protobuf基于反射API是怎樣的,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
Go 的 protocol buffer 綁定是用于谷歌的語言無關的數據交換格式,旨在取代 JSON 用于高性能應用程序,目的是把 protocol buffer 系統合并到Go 的類型系統中,并在運行時實現其操作。
protocol buffer提供了一種方法以指定用于傳輸結構化數據的模式。這種模式通常被轉換成一種特定于編程語言的表示形式,稱為綁定,使得使用高級別的接口處理 protobuf 消息變得更容易。
根據新protobuf模塊版本的作者 Joe Tsai、Damien Neil 和 Herbie Ong 的說法,之前的protobuf實現已經不能滿足 Go 開發人員的期望了。具體來說,它雖然提供了 Go 類型和值的視圖,但是忽略了 protocol buffer 類型系統中的信息。
這樣做的后果就是 portobuf 注解的丟失。例如,我們可能想編寫一個遍歷日志條目并清除任何注解(annotation)為包含敏感數據的字段的函數。注解不是 Go 類型系統的一部分。
舊的 portobuf 模塊的另一個局限是依賴于靜態綁定,從而阻礙了動態消息的使用,而動態消息的類型在編譯時不是完全可知的。
新的 protobuf 模塊 (版本為 APIv2)基于這個假設:protobuf Message 必須完全指定消息的行為,并使用反射以提供 protobuf 類型的完整視圖。Go protobuf APIv2 的基石是新的 proto.Message 接口,可用于所有生成的消息類型,并提供了訪問消息內容的方式。這包括所有 protobuf 字段,可以使用 protoreflect.Message.Range 方式對它們進行迭代。該方法既可以處理動態消息,也可以訪問消息選項。下面例子說明如何處理消息以在進一步處理前清除其包含的所有敏感信息:
// Redact清除pb中的每個敏感字段。
func Redact(pb proto.Message) {
m := pb.ProtoReflect()
m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
opts := fd.Options().(*descriptorpb.FieldOptions)
if proto.GetExtension(opts, policypb.E_NonSensitive).(bool) {
return true
}
m.Clear(fd)
return true
})
}
然而,幾個Hacker News評論者指出,Go protobuf APIv2的版本控制有點讓人感到困惑 。開發人員需要把新版本綁定到一個特定的存儲庫,而不能使用新的版本擴展現有的存儲庫,并把它標記為 v2。Damien Neil 解釋了這一決定背后的原因,如下所示:
我們可以把新的API標記為v2:在導入路徑中,把v1和v2清楚地區分開來。讓人感到困惑的:google.golang.org/protobuf@v1不存在,而v2存在。10年后,希望沒人關心這個舊的github.com/golang/protobuf,那么,這個令人困惑的事就不存在了。我們可以把新的API標記為v1:在導入路徑中難以清楚地區分開來。把google.golang.org/protobuf的第一個版本標記為v1是有意義的。如果我們認為它是個糟糕的想法,那么,從v1轉到v2比從v2回退到v1更容易一些。
此外,Go protobuf APIv2 將從 1.20 版開始。Neil 對此做了的解釋,這樣的目的是避免在錯誤報告中出現版本重疊產生的歧義, 他認為 Go protobuf APIv1 永遠不會有 1.20 版。
最后要注意的是,APIv1 不會被 APIv2 淘汰,它會得到無限期維護。事實上,其最新的實現(1.4 版)是在 APIv2 之上實現的。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。