copier
Repositori Open Source: jinzhu/copier: Copier for golang, copy value from struct to struct and more (github.com)
Dokumentasi: jinzhu/copier: Copier for golang, copy value from struct to struct and more (github.com)
Copier adalah library untuk menyalin tipe dalam Go sering digunakan untuk konversi antar struktur penulisnya sama dengan gorm memiliki fitur berikut
- Deep copy
- Menyalin field dengan nama yang sama
- Menyalin slice
- Menyalin map
- Menyalin method
Karena penyalinan copier bergantung pada refleksi akan ada kerugian performa. Umumnya library jenis penyalinan tipe seperti ini terbagi menjadi dua kategori satu berdasarkan refleksi seperti copier ini yang lain berdasarkan generasi kode dengan menghasilkan kode konversi tipe metode ini tidak menyebabkan kerugian performa library serupa adalah jmattheis/goverter.
Instalasi
go get github.com/jinzhu/copierPenggunaan
Library ini sangat sederhana untuk digunakan namun sangat praktis. Hanya mengekspos dua fungsi satu adalah copier.Copy.
func Copy(toValue interface{}, fromValue interface{}) (err error)Yang lain adalah copier.CopyWithOption yang terakhir dapat melakukan beberapa konfigurasi kustom pada perilaku penyalinan secara default tidak akan melakukan deep copy.
type Option struct {
IgnoreEmpty bool
CaseSensitive bool
DeepCopy bool
FieldNameMapping []FieldNameMapping
}
func CopyWithOption(toValue interface{}, fromValue interface{}, opt Option) (err error)Berikut adalah contoh konversi struktur tipe berbeda User dan Student adalah dua tipe yang sama sekali berbeda tidak ada asosiasi apapun.
type User struct {
Id string
Name string
// Abaikan field ini saat sebagai struktur target
Address string `copier:"-"`
}
type Student struct {
// Tentukan nama field
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)
}Output
{StudentId:123 StudentName:jack Address:usa School:MIT Class:AI}
{Id:123 Name:jack Address:}Berikut penyalinan slice
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)
}Output
[{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:}]Menyalin map
type User struct {
Id string
Name string
// Abaikan field ini saat sebagai struktur target
Address string `copier:"-"`
}
type Student struct {
// Tentukan nama field
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)
}Output
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:}]Kustomisasi
Juga dapat menyesuaikan metode konversi cukup dengan mengirimkan copier.TypeConverter
type TypeConverter struct {
SrcType interface{}
DstType interface{}
Fn func(src interface{}) (dst interface{}, err error)
}Seperti berikut
type User struct {
Id string
Name string
// Abaikan field ini saat sebagai struktur target
Address string `copier:"-"`
}
type Student struct {
// Tentukan nama field
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("error type")
}
return User{
Id: s.StudentId,
}, nil
},
},
},
FieldNameMapping: nil,
}); err != nil {
panic(err)
}
fmt.Printf("%+v\n", src)
fmt.Printf("%+v\n", dest)
}Output
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:}]