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

In my gRPC service, which was written in golang , I have such rpc method called CreateCity. As you can see, in this method, I want to create a new record in the database and return all the information about this record as a response.

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
}

proto文件如下所示:

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,
}
评论
qqgsd
qqgsd

我相信做您想要做的最好的选择是使用反射并遍历源结构的所有字段,将它们与目标结构进行比较,并在它们匹配时分配它们。

A quick google search turned up this package: https://github.com/stroiman/go-automapper. (I haven't used it myself, just putting it here as an example)
The code you'd want is here: here.
Don't want to include the code in this answer since you might want to change it - but the general idea is there.

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

点赞
评论
aut_id
aut_id

You can use json.Marshal create json byte array and then json.Unmarshal

inrec, _ := json.Marshal(request.GetCity())
json.Unmarshal(inrec, &city)
点赞
评论