Как присвоить значение повторяющемуся полю oneof в сообщении protobuf?

# #go #protocol-buffers

Вопрос:

У меня есть сообщение protobuf CoverageReport, подобное этому:

  message Deductible {
  double amount = 1;
  string currency = 2;
}

message Insurance{
  string type = 1;
  string policyNumber = 2;
  string agreementName = 3;
  string appliedTo = 4;
  string validFrom = 5;
  string validTo = 6;
  Deductible deductible = 7;
}

message Warranty {
  string type = 1;
  string warrantyType = 2;
  string agreementName = 3;
  string appliedTo = 4;
  string validFrom = 5;
  string validTo = 6;
}

message Coverage {
  oneof item {
    Insurance insurance = 1;
    Warranty warranty = 2;
  }
}

message CoverageReport {
  bool coverageAppliance = 1;
  repeated Coverage coverages = 2;
}
 

В своей программе я пытаюсь присвоить значения экземпляру сообщения, но я не уверен, как назначить покрытие поля oneof, которое затем должно быть добавлено к покрытиям, как это
Я получаю ответ от api, который я включаю в структуру CoverageReport, которая имеет структуру, аналогичную protobuf. Затем мне нужно создать сообщение protobuf, используя значения из структуры. Но, похоже, это не работает, чтобы подписаться на одно из полей!

 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 *CoverageReport


err = json.Unmarshal(body, amp;coveragereport)

var cr *vcsproto.CoverageReport

    if coveragereport.CoverageAppliance == "Yes" {
        cr.CoverageAppliance = true
    }

    for _, item := range coveragereport.Coverages {
        
        if item.Type == "Warranty"{

            var warranty *vcsproto.Warranty 
            
            warranty.Type = item.Type
            warranty.WarrantyType = item.WarrantyType
            warranty.AgreementName = item.AgreementName
            warranty.AppliedTo = item.AppliedTo
            warranty.ValidFrom = item.ValidFrom
            warranty.ValidTo = item.ValidTo

            var coverage *vcsproto.Coverage
            coverage.Item.Warranty = warranty

            cr.Coverages = append(cr.Coverages, coverage)

        } else {

            var insurance *vcsproto.Insurance
             
            insurance.Type = item.Type
            insurance.PolicyNumber = item.PolicyNumber
            insurance.AgreementName = item.AgreementName
            insurance.AppliedTo = item.AppliedTo
            insurance.ValidFrom = item.ValidFrom
            insurance.ValidTo = item.ValidTo. 
            insurance.Deductible.Currency = item.Deductible.Currency 
            insurance.Deductible.Amount = item.Deductible.Amount 

            var coverage *vcsproto.Coverage
            coverage.Item.Insurance = Insurance

            cr.Coverages = append(cr.Coverages, coverage)

        }
    }
 

Комментарии:

1. Используйте генератор Go protobuf для создания типов Go для ваших типов protobuf. Вы увидите , что он создает тип интерфейса для Coverage Insurance Warranty возможных реализаций и с ними, которые вы можете добавить в Coverages поле.

Ответ №1:

Взгляните на сгенерированный код здесь.

Вы назначаете не непосредственно Warranty Insurance подполям nor, а непосредственно Item полю. так coverage.Item = {insurance/warranty} должно получиться.

Также обратите внимание, что в своем коде, который вы назначаете coverage.Item.Insurance = Insurance , вы, вероятно, имели Insurance insurance в виду, что вместо переменной будет вторая.