Я пытаюсь создать структуру protobuf из
type FlatMessage map[string][]byte
, и я пытаюсь установить значения вложенных полей.
У меня есть метод
func (fm *FlatMessage) Unflatten() (pb.Message, error)
для преобразования плоского сообщения в структурированный protobuf.
У меня также есть вспомогательная функция с именем analyze
, которая принимает структуру типа pb.Message
и возвращает map[int]*ProtoField
где:
type ProtoField struct {
Name string
Type reflect.Type
}
т.е. analyze
traversses pb.Message
рекурсивно и собирает всю необходимую мне информацию об этом.Все идет нормально.
Теперь, когда я иду ключ за ключом через мой FlatMessage
, ключ - это кодированный номер поля соответствующего поля protobuf, и я могу установить его, используя отражение, например:
r := reflect.ValueOf(&result).Elem().FieldByName(field.Name)
if r.IsValid() {
r.Set(scalarValue)
}
, но это работает только тогда, когда рассматриваемый field.Name
не относится к вложенному полю, т. Е. Установка OldV1Id
работает нормально, но попытка установить Profile.Id
или, скажем, Destination.Address.TypeOfNumber
, приводит к:
panic: reflect: call of reflect.Value.Set on zero Value [recovered]
panic: reflect: call of reflect.Value.Set on zero Value
Я понимаю, что это связано с тем, что мой r
становится <invalid Value>
при вызове во вложенном поле, но как я могу обойти это?
Мой r
, конечно, не valid
, не адресуемый и не устанавливаемый.Я могу сделать из него reflect.New
, но я не могу понять, как установить этот новый reflect.Value
таким образом, чтобы поле моих исходных структур изменилось.Независимо от того, что я делаю, моя функция не изменяет поля с вложенными именами с помощью этого подхода.
Еще одно решение, которое я попробовал, - это добавить значение Reflect.Value в мою структуру ProtoField
и изменить analyze
, добавив reflect.ValueOf(s).Field(i)
, где s
- это структура верхнего уровня interface{}
и i
- это его i-е поле.Затем, когда я сталкиваюсь с вложенным полем, я вызываю r := reflect.ValueOf(field.Value)
, но тогда проблема в том, что я не могу вызвать r.Set(scalarValue)
из-за несовместимых типов.
Любая помощь или понимание очень ценится.