Невозможно вставить сообщение в сообщение из-за автоматически сгенерированного указателя - PullRequest
2 голосов
/ 10 июня 2019

У меня есть следующие 3 сообщения protobuf. * ​​1001 *

message Item {
    uint32 ID = 1;
    string Name = 2;
    ...
}

message ItemIdsRequest{
    string batchUUID = 1;
    repeated uint32 itemIds = 2;
}

message ItemsResponse{
    string batchUUID = 1;
    repeated Item items = 2;
}

Функция извлекает список идентификаторов элементов для последующего извлечения всех его деталей. Эти идентификаторы хранятся в сообщении ItemIdsRequest вместе с batchUUID для агрегирования с использованием источников событий.

Затем функция извлекает все детали как []messages.Item из среза int в messages.ItemIdsRequest. Я копирую batchUUID из сообщения ItemIdsRequest в message.ItemsResponse.

Но когда я пытаюсь скопировать возвращенное []messages.Item сообщение ниже, я получаю сообщение об ошибке cannot use items (type []messages.Item as type []*item)

// returns []messages.Item
itemsPB, _ := api.getItems("", items.ItemIds...)

itemsResponse := &messages.ItemsResponse{
    BatchUUID: uuid.NewV4().String(),
    Items:   itemsPB,
}

Я не могу изменить функцию на следующую, потому что элемент является указателем, а не частью элементов, которую возвращает функция. И я не могу заставить функции возвращать 'message.ItemsResponse'.

TLDR : У меня есть две отдельные структуры protobuf. Я пытаюсь установить []messages.items в свойстве messages.ItemsResponse items, но мне это запрещено, поскольку сгенерированный код protobuf делает свойство messages.ItemsResponse items указателем. Когда я редактирую автоматически сгенерированный код и удаляю указатель ... все работает как положено.

type ItemsResponse struct {
    BatchUUID            string   `protobuf:"bytes,1,opt,name=batchUUID,proto3" json:"batchUUID,omitempty"`
    Items                []*Item  `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"`
    XXX_NoUnkeyedLiteral struct{} `json:"-"`
    XXX_unrecognized     []byte   `json:"-"`
    XXX_sizecache        int32    `json:"-"`
}

Я новичок в protobuf и не эксперт по указателям (хотел бы), поэтому я мог бы также использовать некоторую помощь в понимании, почему он автоматически сгенерирован в указатель.

1 Ответ

0 голосов
/ 13 июня 2019

Protobuf документирует, что для повторяющихся полей сообщения сгенерированный код Go будет использовать фрагмент указателей. Это допускает необязательные значения, потому что в Go структуры не могут быть nil, а указатели могут.

Если у вас есть фрагмент структур и вы хотите присвоить его переменной или полю, являющемуся фрагментом указателей, вы должны «вручную» получить это значение.

Для этого используйте простой цикл:

// returns []messages.Item
itemsPB, _ := api.getItems("", items.ItemIds...)

itemPtrs := make([]*messages.Item, len(itemsPB))
for i := range itemsPB {
    itemPtrs[i] = &itemsPB[i]
}

itemsResponse := &messages.ItemsResponse{
    BatchUUID: uuid.NewV4().String(),
    Items:     itemPtrs,
}

Обратите внимание, что срез указателей, который мы собираем выше, указывает на элементы исходного среза itemsPB.

Если вы измените api.getItems(), чтобы он возвращал фрагмент указателей ([]*messages.Item), вы можете назначить это без необходимости создания фрагмента указателей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...