- 生成的代码需要根据用到的包增加import(严格讲,还应该go get以防go.mod中没有require该包)
- 基础类型的转换,不用cast,直接转换成具体的语句(会有点工作量来写这些函数)
- 支持字段名称及转换格式的自定义mapping规则
- 支持 []string 和 string 之间的转换,默认使用","作为分隔符,也可以自定义分隔符
- 支持 struct 到 map[string]interface{} 和 map[string]string 的转换
- 支持 map[string]string 到 struct 的转换
- 支持 map[string]interface{} 到 struct 的转换
- struct中包含struct时的转换方法
- 支持配置忽略某些字段
- 支持转换的时候统一字段名前缀(可配置原字段或目标字段使用前缀)
仿照 MapStruct – Java bean mappings, the easy way! 。
代码实现参考google/wire: Compile-time Dependency Injection for Go (github.com)。
定义两个类,如:
type Demo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
CreatedAt string `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
Timeout string `protobuf:"varint,4,opt,name=timeout,proto3" json:"timeout,omitempty"`
Price string `protobuf:"bytes,5,opt,name=price,proto3" json:"price,omitempty"`
TenantId string `protobuf:"bytes,6,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"`
}type Demo struct {
ID uint64
Name string
CreatedAt time.Time
Timeout time.Duration
Price decimal.Decimal
TenantID uint64
}定义转换,如:
//go:build mapstruct
// +build mapstruct
package examples
import (
"github.com/aiscrm/mapstruct/examples/entity"
"github.com/aiscrm/mapstruct/examples/proto"
)
// UnmarshalDemo 转换struct方法定义
func UnmarshalDemo(src *proto.Demo, target *entity.Demo) error {
return nil
}还可以定义名称的映射关系及format(如时间格式、decimal精度、字典转换等)
先做简单的,就是基础类型、decimal.Decimal、time.Time、time.duration的转换。后面再做内嵌struct的转换
步骤:
- 找出含
//+build mapstruct的go文件 - 解析这些文件
- 解析出package名称,文件路径(也会作为输出路径)
- 解析出所有的import,包含匿名import,有的可能是命名import
- 找出这些文件中定义的所有符合范式的func,及参数和返回值,及字段映射mapping定义
- 根据func的参数和返回值,找出定义struct的go文件,并解析出struct的pkg,import,字段等
- 转换,使用转换器,在其中定义转换不同类型的方法
- 输出