Go gRPC服务返回对象数组时的类型错误排查与解决
问题原因
Go是强类型语言,你的代码里存在两种完全不兼容的类型:
- 自定义的
[]InventoryData:值类型切片,对应你本地定义的结构体 []*pb.DealerInventory_InventoryData:proto编译生成的指针类型切片,是gRPC返回消息要求的类型
即便两者字段结构完全一致,Go也不允许直接赋值或隐式转换,这就是触发类型错误的根本原因。
解决方法
需要手动遍历自定义切片,将每个InventoryData实例转换为proto生成的*pb.DealerInventory_InventoryData对象,再组成新的切片赋值给返回消息。
修改后的Greet方法代码如下:
func (s *Server) Greet(ctx context.Context, in *pb.GreetRequest) (*pb.DealerInventory, error) { result := getInventoryData() // 初始化proto类型的Inventory切片 protoInventory := make([]*pb.DealerInventory_InventoryData, len(result.Inventory)) for i, item := range result.Inventory { protoInventory[i] = &pb.DealerInventory_InventoryData{ DHCost: item.DHCost, DealerNumber: item.DealerNumber, ModelYear: item.ModelYear, ExteriorColor: item.ExteriorColor, InteriorColor: item.InteriorColor, ModelGroupName: item.ModelGroupName, Transmission: item.Transmission, ModelMSRP: item.ModelMSRP, NumberOnSite: item.NumberOnSite, NumberInTransit: item.NumberInTransit, } } return &pb.DealerInventory{ Inventory: protoInventory, Vehiclemodelseriesname: result.Vehiclemodelseriesname, ZipCodeSent: result.ZipCodeSent, }, nil }
优化建议
如果后续字段较多或需要频繁转换,可以封装一个通用转换函数简化代码:
func convertToProtoInventoryData(data InventoryData) *pb.DealerInventory_InventoryData { return &pb.DealerInventory_InventoryData{ DHCost: data.DHCost, DealerNumber: data.DealerNumber, ModelYear: data.ModelYear, ExteriorColor: data.ExteriorColor, InteriorColor: data.InteriorColor, ModelGroupName: data.ModelGroupName, Transmission: data.Transmission, ModelMSRP: data.ModelMSRP, NumberOnSite: data.NumberOnSite, NumberInTransit: data.NumberInTransit, } }
遍历时代码可简化为:
for i, item := range result.Inventory { protoInventory[i] = convertToProtoInventoryData(item) }
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

