Perangkap Unmarshaling Unmarshaling Unknown Protobuf Messages
Ketidakupayaan proto.Unmarshal untuk mengendalikan jenis antara muka{} ialah aspek penting untuk difahami. Tandatangan kaedahnya menetapkan lulus proto.Hujah mesej, yang dilaksanakan oleh jenis protobuffer konkrit.
Mengatasi Cabaran
Apabila berurusan dengan muatan protobuffer mentah yang tidak mempunyai konteks tambahan , adalah penting untuk mempunyai sekurang-kurangnya beberapa maklumat pengenalpastian (cth., rentetan atau nombor) di samping kepingan bait. Maklumat ini boleh digunakan untuk memetakan kepada mesej konkrit protobuffer tertentu. Anda kemudiannya boleh menggunakan pernyataan suis untuk membuat instantiate jenis yang sesuai dan menyerahkannya kepada Unmarshal:
switch atLeastSomething { case "foo": message = &mypb.Foo{} case "bar": message = &mypb.Bar{} } _ = proto.Unmarshal(data, message)
Merangkul yang Tidak Dapat Diramal: Menyahkod Mesej Yang Tidak Diketahui Sepenuhnya
Dalam keadaan yang jarang berlaku , anda mungkin menghadapi muatan protobuffer yang tidak diketahui sepenuhnya. Pakej protowire menyediakan penyelesaian untuk mengekstrak beberapa maklumat daripadanya, walaupun dengan batasan yang wujud. Kandungan muatan boleh diperoleh semula, tetapi dengan semantik yang lebih lemah.
Butiran Pelaksanaan
Berikut ialah penghurai yang dipermudahkan untuk mesej proto yang tidak diketahui:
func parseUnknown(b []byte) []Field { // Data model type Field struct { Tag Tag Val Val } type Tag struct { Num int32 Type protowire.Type } type Val struct { Payload interface{} Length int } // Parsing algorithm fields := make([]Field, 0) for len(b) > 0 { n, t, fieldlen := protowire.ConsumeField(b) if fieldlen < 1 { return nil } ... // Parsing logic fields = append(fields, field) b = b[fieldlen:] } return fields }
Input Contoh dan Output
Dengan input sampel:
message Foo { string a = 1; string b = 2; Bar bar = 3; } message Bar { string c = 1; } &test.Foo{A: "A", B: "B", Bar: &test.Bar{C: "C"}}
Outputnya ialah:
Field{Tag:Tag{Num:1, Type:2}, Val:Val{Payload:[]uint8{0x41}, Length:1}} Field{Tag:Tag{Num:2, Type:2}, Val:Val{Payload:[]uint8{0x42}, Length:1}} Field{Tag:Tag{Num:1, Type:2}, Val:Val{Payload:[]uint8{0x43}, Length:1}} Field{Tag:Tag{Num:3, Type:2}, Val:Val{Payload:[]Field{Field{Tag:Tag{Num:1, Type:2}, Val:Val{Payload:[]uint8{0x43}, Length:1}}}, Length:3}}
Pertimbangan Tambahan
Alternatif: Mana-mana dan Antara Muka{}
Walaupun Any pada mulanya mungkin kelihatan seperti pilihan yang sesuai untuk mesej yang tidak diketahui, ia mempunyai struktur yang ditetapkan dengan ketat dan tidak boleh digunakan untuk menyahkod muatan yang tidak diketahui. Tambahan pula, protowire tidak boleh digunakan untuk Any kerana struktur khususnya.
Atas ialah kandungan terperinci Bagaimana Saya Boleh Menyahmarshal Mesej Protobuf Tidak Diketahui dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!