dpa31905 2019-06-10 15:01
浏览 63
已采纳

由于自动生成了指针,因此无法在消息中嵌入消息

I have the following 3 protobuf messages.

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;
}

A function retrieves a list of item ID's to later fetch all its details. These ID's are stored in the mssage ItemIdsRequest along with a batchUUID for aggregating via event-sourcing.

Then a function retrieves all details as a []messages.Item from the int slice in messages.ItemIdsRequest. I copy the batchUUID from the message ItemIdsRequest over into the message.ItemsResponse.

But when I try to copy the returned []messages.Item into belows message I get the error 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,
}

I cannot change the function to the following, because the item is a pointer, not the slice of items which the function returns. And I cannot have the functions return 'message.ItemsResponse'.

TLDR: I have two seperate protobuf structs. I am trying to set the []messages.items in the messages.ItemsResponse items property but I am not allowed to because the generated protobuf code makes the messages.ItemsResponse items property a pointer. When I edit the autogenerated code and remove the pointer... everything works as intended.

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:"-"`
}

I am new to protobuf and no expert on pointers (wanting to be) so I could also use some help understanding why its autogenerated into a pointer.

  • 写回答

1条回答 默认 最新

  • doufu2396 2019-06-13 12:38
    关注

    Protobuf documents that for repeated message fields the generated Go code will use a slice of pointers. This allows optional values, because in Go structs cannot be nil, but pointers can.

    If you have a slice of structs and you want to assign that to a variable or field which is a slice of pointers, you have to "manually" produce that value.

    Use a simple loop to do that:

    // 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,
    }
    

    Note that the slice of pointers we assemble above points to the elements of the original itemsPB slice.

    If you modify api.getItems() to return a slice of pointers ([]*messages.Item), you could assign that without having to create a slice of pointers.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 matlab有关常微分方程的问题求解决
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?
  • ¥100 求三轴之间相互配合画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考