根据函数类型声明自动生成转换代码,支持转换/深拷贝模式,支持应用扩展自定义转换函数/过滤/忽略特定字段等选项
- 支持conv/deepCopy模式
- 支持范型
- 支持自动解指针
- 支持基础类型/map/slice/array/struct 转换
- 支持基础类型自动向上转型
- 支持Alias类型自动转换
- 支持embed field自动解包
- 支持自引用对象,支持递归转换
- 自动处理同名包冲突
- 支持string <-> []byte/[]rune 互转
- 支持Pointer <-> Struct 互转
- 支持Array <-> Slice 互转
- 支持扩展自定义转换/过滤/忽略选项
生成命令:
go run github.com/ycl2018/go-conv@latest ./...
conv模式是默认使用的类型转换模式,采用浅拷贝,提高转换性能
// go-conv:generate
var Foo2Bar func (src *Foo) *Bar
type Foo struct {
Str string
Slice []string
Map map[string]string
Pointer string
Alias string
}
type Bar struct {
Str string
Slice []string
Map map[string]string
Pointer *string
Alias StringAlias
}
type StringAlias string
generated:
// Code generated by github.com/ycl2018/go-conv DO NOT EDIT.
package testdata
func FooToBar(src *Foo) (dst *Bar) {
if src != nil {
dst = new(Bar)
dst.Str = src.Str
dst.Slice = src.Slice
dst.Map = src.Map
dst.Pointer = &src.Pointer
dst.Alias = (StringAlias)(src.Alias)
}
return
}
func init() {
Foo2Bar = FooToBar
}
copy模式使用深拷贝模式拷贝结构体的每个字段
// go-conv:generate
// go-conv:copy
var Foo2Bar func(src *Foo) *Bar
type Foo struct {
Str string
Slice []string
Map map[string]string
Pointer string
Alias string
}
type Bar struct {
Str string
Slice []string
Map map[string]string
Pointer *string
Alias StringAlias
}
type StringAlias string
generated:
// Code generated by github.com/ycl2018/go-conv DO NOT EDIT.
package example
func CopyPtrFooToPtrBar(src *Foo) (dst *Bar) {
if src != nil {
dst = new(Bar)
dst.Str = src.Str
if len(src.Slice) > 0 {
dst.Slice = make([]string, len(src.Slice))
for i := 0; i < len(src.Slice); i++ {
dst.Slice[i] = src.Slice[i]
}
}
if len(src.Map) > 0 {
dst.Map = make(map[string]string, len(src.Map))
for k, v := range src.Map {
var tmpK string
var tmpV string
tmpK = k
tmpV = v
dst.Map[tmpK] = tmpV
}
}
dst.Pointer = new(string)
*dst.Pointer = src.Pointer
dst.Alias = StringAlias(src.Alias)
}
return
}
func init() {
Foo2Bar = CopyPtrFooToPtrBar
}
可使用go-conv:apply 指定要应用的配置,编程式ide友好,配置更方便
package cases
import (
"strconv"
"github.com/ycl2018/go-conv/option"
"github.com/ycl2018/go-conv/testdata/a"
"github.com/ycl2018/go-conv/testdata/b"
)
// Struct2Struct conv a Basic to b Basic
// go-conv:generate
// go-conv:apply basicConvOpts
var Struct2Struct func(p *a.Struct) *b.Struct
var basicConvOpts = []option.Option{
option.WithIgnoreFields(a.Struct{}, []string{"Pojo"}),
option.WithIgnoreTypes(a.Student{}, "Student3"),
option.WithTransformer(transfer, "Student2.Class.Grade"),
option.WithFilter(filter, "Student2.Teachers"),
option.WithFieldMatch(a.Struct{}, map[string]string{
"Match": "Match_",
}),
option.WithMatchCaseInsensitive(),
option.WithNoInitFunc(),
}
func transfer(t int) string {
return strconv.Itoa(t)
}
func filter(arr []string) []string {
return arr
}
// Code generated by github.com/ycl2018/go-conv DO NOT EDIT.
package cases
import (
"github.com/ycl2018/go-conv/testdata/a"
"github.com/ycl2018/go-conv/testdata/b"
)
func PtrAStructToPtrBStruct(src *a.Struct) (dst *b.Struct) {
if src != nil {
dst = new(b.Struct)
dst.Student.Name = src.Student.Name
dst.Student.Class.Name = src.Student.Class.Name
dst.Student.Class.Grade = string(src.Student.Class.Grade)
dst.Student.Teachers = src.Student.Teachers
dst.Student2.Name = src.Student2.Name
dst.Student2.Class.Name = src.Student2.Class.Name
// apply transfer option on transfer
transferredSrcStudent2ClassGrade := transfer(src.Student2.Class.Grade)
dst.Student2.Class.Grade = transferredSrcStudent2ClassGrade
// apply filter option on filter
filteredSrcStudent2Teachers := filter(src.Student2.Teachers)
dst.Student2.Teachers = filteredSrcStudent2Teachers
// apply ignore option on src.Student3
// apply ignore option on src.Pojo
dst.Match_ = src.Match
dst.Caseinsensitive = src.CaseInsensitive
}
return
}