如何用数据动态填充结构?



在我的gRPC服务中,它是用golang编写的,我有这样一个叫做CreateCityrpc method。如您所见,在此方法中,我想在数据库中创建一个新记录,并返回有关该记录的所有信息作为响应。

func (server *Server) CreateCity(context context.Context, request *proto.CreateCityRequest) (*proto.CreateCityResponse, error) {
city := proto.City {
Name: request.GetCity().Name,
Country: request.GetCity().Country,
}
err := databases.DBGORM.Table("city").Create(&city).Error
if err != nil {
utils.Logger().Println(err.Error())
return nil, status.Errorf(codes.Internal, err.Error())
}
result := &proto.CreateCityResponse {
City: &city,
}
return result, nil
}

原型文件如下所示:

syntax = "proto3";
package proto;
import "google/protobuf/wrappers.proto";
import "google/protobuf/timestamp.proto";
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
option go_package = "./proto";
service CityService {
rpc CreateCity(CreateCityRequest) returns (CreateCityResponse) {}
}
message City {
google.protobuf.StringValue name = 1 [json_name = "name", (gogoproto.jsontag) = "name", (gogoproto.wktpointer) = true];
google.protobuf.StringValue country = 2 [json_name = "country", (gogoproto.jsontag) = "country", (gogoproto.wktpointer) = true];
}
message CreateDealerGroupRequest {
City city = 1;
}
message CreateDealerGroupResponse {
City city = 1;
}

是否可以在不显式指定名称的情况下用数据动态填充结构?正如您现在所看到的,我明确指定了字段的名称及其值:

city := proto.City {
Name: request.GetCity().Name,
Country: request.GetCity().Country,
}

您可以使用json.Marshal创建 json 字节数组,然后json.Unmarshal

inrec, _ := json.Marshal(request.GetCity())
json.Unmarshal(inrec, &city)

我相信你做你想做的事的最佳选择是使用反射并遍历源结构的所有字段,将它们与目标结构进行比较,如果它们匹配,则分配它们。

快速的谷歌搜索发现了这个包:https://github.com/stroiman/go-automapper。 (我自己没有用过,只是举在这里作为例子(
你想要的代码在这里:这里。
不想在此答案中包含代码,因为您可能想更改它 - 但总体思路就在那里。

就个人而言,如果可行,我会采用手动方法(就像您现在所做的那样(。 依赖反射会更慢,但也许更重要的是,对模型的更改可能会以不可预见的方式影响映射。 仅取决于您的用例 imo。

最新更新