golang,go,博客,开源,编程
这都2025年了,你还在一个一个手动复制字段吗?
jinzhu/copier
是一个 Go 语言库,用于深度复制结构体(struct)及其字段,支持嵌套结构体、切片、数组等的复制。这个库的主要目标是通过简单的 API 提供高效、易用的对象复制功能,避免手动编写复制逻辑。
struct tag
) 来定制字段映射规则,例如可以指定不同字段名的复制规则。copier
会根据字段名进行自动映射,只要源结构体和目标结构体的字段名相同。copier
在性能上相对较好,但在处理非常大的数据量时,可能还是比手动复制稍慢一些。copier
支持复制结构体指针,避免了手动解引用的麻烦。可以通过 go get
安装 jinzhu/copier
:
go get github.com/jinzhu/copier
假设我们有一个源结构体和目标结构体,想要将源结构体的值复制到目标结构体:
package main
import (
"fmt"
"github.com/jinzhu/copier"
)
type Person struct {
Name string
Age int
Email string
}
type Employee struct {
Name string
Age int
Email string
}
func main() {
person := Person{
Name: "John Doe",
Age: 30,
Email: "john@example.com",
}
var employee Employee
// 复制 person 到 employee
copier.Copy(&employee, &person)
fmt.Printf("Employee: %+v\n", employee)
}
输出:
Employee: {Name:John Doe Age:30 Email:john@example.com}
在这个示例中,copier.Copy(&employee, &person)
会自动将 person
中的值复制到 employee
中,前提是两个结构体字段名一致。
type Person struct {
Name string `copier:"FullName"`
Age int
}
type Employee struct {
FullName string
Age int
}
func main() {
person := Person{
Name: "John Doe",
Age: 30,
}
var employee Employee
// 将 Person 的 Name 字段映射到 Employee 的 FullName 字段
copier.Copy(&employee, &person)
fmt.Printf("Employee: %+v\n", employee)
}
copier
会自动递归复制:type Address struct {
City string
Country string
}
type Person struct {
Name string
Address Address
}
type Employee struct {
Name string
Address Address
}
func main() {
person := Person{
Name: "John Doe",
Address: Address{
City: "New York",
Country: "USA",
},
}
var employee Employee
copier.Copy(&employee, &person)
fmt.Printf("Employee: %+v\n", employee)
}
jinzhu/copier
提供了一些配置选项来控制复制行为:
copier
会跳过复制过程。如果需要强制复制零值,可以通过设置 copier.Option
来实现。copier.CopyWithOption(&destination, &source, copier.Option{IgnoreEmpty: false})
虽然 copier
会尽可能做得智能,但是你仍然应该检查目标结构体的字段和源结构体字段是否完全匹配,特别是在复杂的嵌套结构体的情况下。如果有不兼容的字段类型,copier
会抛出错误。
jinzhu/copier
是一个功能强大且易用的 Go 库,适用于那些需要批量复制结构体的场景。它不仅支持基本的字段复制,还能处理嵌套结构体、指针等复杂情况,使得对象复制变得简单高效。