copier
Depo: jinzhu/copier: Copier for golang, copy value from struct to struct and more (github.com)
Dokümantasyon: jinzhu/copier: Copier for golang, copy value from struct to struct and more (github.com)
copier Go'da tip kopyalama için bir kütüphanedir. Çoğunlukla struct'tan struct'a dönüşüm için kullanılır. gorm ile aynı yazar tarafından yazılmıştır ve aşağıdaki özelliklere sahiptir:
- Derin kopyalama
- Aynı isimli alanları kopyalama
- Slice'ları kopyalama
- Map'leri kopyalama
- Metodları kopyalama
copier'ın kopyalaması yansıma (reflection) kullandığından bazı performans kayıpları olacaktır. Genel olarak bu tür tip dönüşüm kütüphaneleri iki kategoriye ayrılır: biri copier gibi yansıma tabanlıdır, diğeri kod üretimi tabanlıdır ve tip dönüşüm kodu üretir. Bu yöntem performans kaybına neden olmaz. Benzer bir kütüphane jmattheis/goverter'dır.
Kurulum
go get github.com/jinzhu/copierKullanım
Bu kütüphane kullanımı çok basit ancak oldukça pratiktir. Yalnızca iki fonksiyonu kullanıma sunar. Biri copier.Copy:
func Copy(toValue interface{}, fromValue interface{}) (err error)Diğeri copier.CopyWithOption kopyalama davranışı için bazı özel yapılandırmalara izin verir. Varsayılan olarak derin kopyalama yapılmaz:
type Option struct {
IgnoreEmpty bool
CaseSensitive bool
DeepCopy bool
FieldNameMapping []FieldNameMapping
}
func CopyWithOption(toValue interface{}, fromValue interface{}, opt Option) (err error)Farklı struct türleri arasında dönüşüm örneği. User ve Student struct'ları hiçbir ilişkisi olmayan tamamen farklı türlerdir:
type User struct {
Id string
Name string
// Hedef struct olarak kullanıldığında bu alanı yoksay
Address string `copier:"-"`
}
type Student struct {
// Alan adını belirt
StudentId string `copier:"Id"`
StudentName string `copier:"Name"`
Address string
School string
Class string
}
func main() {
student := Student{
StudentId: "123",
StudentName: "jack",
Address: "usa",
School: "MIT",
Class: "AI",
}
user := User{}
if err := copier.Copy(&user, &student); err != nil {
panic(err)
}
fmt.Printf("%+v\n", student)
fmt.Printf("%+v\n", user)
}Çıktı:
{StudentId:123 StudentName:jack Address:usa School:MIT Class:AI}
{Id:123 Name:jack Address:}Slice kopyalama:
func main() {
student := []Student{
{
StudentId: "123",
StudentName: "jack",
Address: "usa",
School: "MIT",
Class: "AI",
},
{
StudentId: "123",
StudentName: "jack",
Address: "usa",
School: "MIT",
Class: "AI",
},
}
var user []User
if err := copier.Copy(&user, &student); err != nil {
panic(err)
}
fmt.Printf("%+v\n", student)
fmt.Printf("%+v\n", user)
}Çıktı:
[{StudentId:123 StudentName:jack Address:usa School:MIT Class:AI} {StudentId:123 StudentName:jack Address:usa School:MIT Class:AI}]
[{Id:123 Name:jack Address:} {Id:123 Name:jack Address:}]Map kopyalama:
type User struct {
Id string
Name string
// Hedef struct olarak kullanıldığında bu alanı yoksay
Address string `copier:"-"`
}
type Student struct {
// Alan adını belirt
StudentId string `copier:"Id"`
StudentName string `copier:"Name"`
Address string
School string
Class string
}
func main() {
student := Student{
StudentId: "123",
StudentName: "jack",
Address: "usa",
School: "MIT",
Class: "AI",
}
src := make(map[string]Student)
src["a"] = student
src["b"] = student
dest := make(map[string]User)
if err := copier.Copy(&dest, &src); err != nil {
panic(err)
}
fmt.Printf("%+v\n", src)
fmt.Printf("%+v\n", dest)
}Çıktı:
map[a:{StudentId:123 StudentName:jack Address:usa School:MIT Class:AI} b:{StudentId:123 StudentName:jack Address:usa School:MIT Class:AI}]
map[a:{Id:123 Name:jack Address:} b:{Id:123 Name:jack Address:}]Özelleştirme
copier.TypeConverter geçirerek dönüşüm metodunu özelleştirebilirsiniz:
type TypeConverter struct {
SrcType interface{}
DstType interface{}
Fn func(src interface{}) (dst interface{}, err error)
}Aşağıdaki gibi:
type User struct {
Id string
Name string
// Hedef struct olarak kullanıldığında bu alanı yoksay
Address string `copier:"-"`
}
type Student struct {
// Alan adını belirt
StudentId string `copier:"Id"`
StudentName string `copier:"Name"`
Address string
School string
Class string
}
func main() {
student := Student{
StudentId: "123",
StudentName: "jack",
Address: "usa",
School: "MIT",
Class: "AI",
}
src := make(map[string]Student)
src["a"] = student
src["b"] = student
dest := make(map[string]User)
if err := copier.CopyWithOption(&dest, &src, copier.Option{
IgnoreEmpty: false,
CaseSensitive: false,
DeepCopy: false,
Converters: []copier.TypeConverter{
{
SrcType: Student{},
DstType: User{},
Fn: func(src interface{}) (dst interface{}, err error) {
s, ok := src.(Student)
if !ok {
return User{}, errors.New("hata türü")
}
return User{
Id: s.StudentId,
}, nil
},
},
},
FieldNameMapping: nil,
}); err != nil {
panic(err)
}
fmt.Printf("%+v\n", src)
fmt.Printf("%+v\n", dest)
}Çıktı:
map[a:{StudentId:123 StudentName:jack Address:usa School:MIT Class:AI} b:{StudentId:123 StudentName:jack Address:usa School:MIT Class:AI}]
map[a:{Id:123 Name: Address:} b:{Id:123 Name: Address:}]