如何为Protobuf消息中的repeated嵌套oneof字段赋值?
问题修复说明
原有代码存在以下核心错误:
- 所有Protobuf生成的结构体指针仅声明未初始化,直接赋值会触发空指针panic
- Go Protobuf的oneof字段不能直接操作
Item下的属性,必须使用protoc生成的专用oneof包装类型赋值 - 存在变量名大小写拼写错误、嵌套结构体未初始化的问题
正确实现代码
type CoverageReport struct { CoverageAppliance string `json:"coverageAppliance"` Coverages []struct { Type string `json:"type"` PolicyNumber string `json:"policyNumber,omitempty"` AgreementName string `json:"agreementName"` AppliedTo string `json:"appliedTo"` ValidFrom string `json:"validFrom"` ValidTo string `json:"validTo"` Deductible struct { Amount float64 `json:"amount"` Currency string `json:"currency"` } `json:"deductible,omitempty"` WarrantyType string `json:"warrantyType,omitempty"` } `json:"coverages"` } var coveragereport = new(CoverageReport) // 必须判断Unmarshal错误 err = json.Unmarshal(body, coveragereport) if err != nil { // 自行处理错误逻辑 panic(err) } // 先初始化Protobuf的CoverageReport实例 cr := &vcsproto.CoverageReport{ CoverageAppliance: coveragereport.CoverageAppliance == "Yes", Coverages: make([]*vcsproto.Coverage, 0, len(coveragereport.Coverages)), } for _, item := range coveragereport.Coverages { // 初始化Coverage实例 coverage := new(vcsproto.Coverage) if item.Type == "Warranty" { // 初始化Warranty并赋值 warranty := &vcsproto.Warranty{ Type: item.Type, WarrantyType: item.WarrantyType, AgreementName: item.AgreementName, AppliedTo: item.AppliedTo, ValidFrom: item.ValidFrom, ValidTo: item.ValidTo, } // oneof字段赋值:用生成的Warranty包装类型 coverage.Item = &vcsproto.Coverage_Warranty{ Warranty: warranty, } } else { // 初始化Deductible deductible := &vcsproto.Deductible{ Amount: item.Deductible.Amount, Currency: item.Deductible.Currency, } // 初始化Insurance并赋值 insurance := &vcsproto.Insurance{ Type: item.Type, PolicyNumber: item.PolicyNumber, AgreementName: item.AgreementName, AppliedTo: item.AppliedTo, ValidFrom: item.ValidFrom, ValidTo: item.ValidTo, Deductible: deductible, } // oneof字段赋值:用生成的Insurance包装类型 coverage.Item = &vcsproto.Coverage_Insurance{ Insurance: insurance, } } // 追加到coverages数组 cr.Coverages = append(cr.Coverages, coverage) }
核心说明
Go Protobuf为oneof字段会自动生成一组以结构体名_字段名命名的包装类型,你只需要把对应类型的实例传入包装结构体,再赋值给Coverage的Item字段即可完成oneof赋值。
内容的提问来源于stack exchange,提问作者user6714507
相关产品推荐
相关产品推荐

