copier
Open-Source-Repository: jinzhu/copier: Copier for golang, copy value from struct to struct and more (github.com)
Dokumentation: jinzhu/copier: Copier for golang, copy value from struct to struct and more (github.com)
Copier ist eine Bibliothek für die Typkopie in Go, die hauptsächlich für die Konvertierung zwischen Strukturen verwendet wird. Der Autor ist derselbe wie bei GORM, und es hat folgende Eigenschaften:
- Tiefenkopie
- Kopieren von gleichnamigen Feldern
- Kopieren von Slices
- Kopieren von Maps
- Kopieren von Methoden
Da die Kopie von Copier auf Reflexion basiert, gibt es gewisse Leistungsverluste. Im Allgemeinen werden solche Typkopie-Bibliotheken in zwei Kategorien unterteilt: eine basiert auf Reflexion, wie Copier, die andere basiert auf Codegenerierung, indem Typkonvertierungscode generiert wird. Diese Methode führt zu keinen Leistungsverlusten, ähnlich wie bei der Bibliothek jmattheis/goverter.
Installation
go get github.com/jinzhu/copierVerwendung
Diese Bibliothek ist sehr einfach zu verwenden, aber äußerst praktisch. Sie stellt nur zwei Funktionen öffentlich zur Verfügung, eine ist copier.Copy.
func Copy(toValue interface{}, fromValue interface{}) (err error)Die andere ist copier.CopyWithOption, mit der das Kopierverhalten angepasst werden kann. Standardmäßig wird keine Tiefenkopie durchgeführt.
type Option struct {
IgnoreEmpty bool
CaseSensitive bool
DeepCopy bool
FieldNameMapping []FieldNameMapping
}
func CopyWithOption(toValue interface{}, fromValue interface{}, opt Option) (err error)Im Folgenden wird ein Beispiel für die Konvertierung zwischen verschiedenen Strukturtypen gezeigt, wobei User und Student zwei völlig unterschiedliche Typen ohne Verbindung sind.
type User struct {
Id string
Name string
// Wird ignoriert, wenn als Zielstruktur verwendet
Address string `copier:"-"`
}
type Student struct {
// Feldname angeben
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)
}Ausgabe
{StudentId:123 StudentName:jack Address:usa School:MIT Class:AI}
{Id:123 Name:jack Address:}Im Folgenden wird das Kopieren von Slices gezeigt
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)
}Ausgabe
[{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 kopieren
type User struct {
Id string
Name string
// Wird ignoriert, wenn als Zielstruktur verwendet
Address string `copier:"-"`
}
type Student struct {
// Feldname angeben
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)
}Ausgabe
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:}]Anpassung
Sie können auch benutzerdefinierte Konvertierungsmethoden definieren, indem Sie copier.TypeConverter übergeben:
type TypeConverter struct {
SrcType interface{}
DstType interface{}
Fn func(src interface{}) (dst interface{}, err error)
}Wie unten gezeigt:
type User struct {
Id string
Name string
// Wird ignoriert, wenn als Zielstruktur verwendet
Address string `copier:"-"`
}
type Student struct {
// Feldname angeben
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)
}Ausgabe
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:}]