首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >每日一库:Copier - Go 语言的结构体复制神器

每日一库:Copier - Go 语言的结构体复制神器

作者头像
七点一刻
发布2026-03-18 19:15:05
发布2026-03-18 19:15:05
860
举报

简介

copier[1] 是一个轻量级的 Go 语言库,专注于简化结构体之间的数据复制。通过自动或自定义的字段映射,它能够高效处理结构体、切片、甚至嵌套类型的复制,减少手动赋值的冗余代码。由知名 GORM[2] 作者 jinzhu 开发,稳定性和设计理念值得信赖。


核心功能

1️⃣结构体 ↔ 结构体复制

  • 自动匹配同名字段:无需配置,自动复制名称和类型相同的字段。
  • 标签支持:通过 copier:"目标字段名" 标签映射不同名称的字段。
  • 嵌套结构体:自动递归复制嵌套的结构体(默认深度复制)。
代码语言:javascript
复制
type User struct {
    Name string
    Age  int
}

type Employee struct {
    Name    string
    Age     int`copier:"UserAge"`// 显式映射到源结构体的 Age 字段
    Salary  float64
}

funcmain() {
    user := User{Name: "Alice", Age: 30}
    employee := Employee{}
    copier.Copy(&employee, &user)
// employee.Name = "Alice", employee.UserAge = 30
}

2️⃣切片 ↔ 切片复制

  • 自动将源切片元素逐个复制到目标切片。
  • 支持不同类型切片(需元素类型可转换)。
代码语言:javascript
复制
users := []User{{Name: "Alice"}, {Name: "Bob"}}
var employees []Employee
copier.Copy(&employees, &users) // employees 成为包含两个 Employee 的切片

3️⃣自定义转换函数

  • 注册函数处理特定类型或字段的转换逻辑(如时间格式、枚举解析),自动处理基础类型转换(如 intint32string[]byte)。
  • 支持自定义转换器:通过 copier.RegisterConverter 注册函数处理复杂类型转换。
代码语言:javascript
复制
copier.CopyWithOption(&dest, &src, copier.Option{
    Converters: []copier.TypeConverter{
        {
            SrcType: time.Time{},
            DstType: copier.String,
            Fn: func(src interface{}) (interface{}, error) {
                return src.(time.Time).Format("2006-01-02"), nil
            },
        },
    },
})

4️⃣忽略字段

  • 使用 copier:"-" 标签跳过指定字段。
代码语言:javascript
复制
type Config struct {
    APIKey string `copier:"-"` // 复制时忽略此字段
    Port   int
}

5️⃣深度复制(Deep Copy)

  • 对指针、切片、映射等引用类型创建独立副本,避免副作用。

6️⃣复制选项(Option)

IgnoreEmpty:跳过源字段为零值(如 ""0nil)的复制。

代码语言:javascript
复制
copier.CopyWithOption(&dest, &src, copier.Option{IgnoreEmpty: true}) // 源字段为空时不覆盖目标

CaseInsensitive:启用不区分大小写的字段匹配(如 Source.Name 匹配 Target.NAME

DeepCopy:深度复制指针、切片等引用类型(默认浅复制)。

代码语言:javascript
复制
src := &User{Addresses: []Address{{City: "NY"}}}
var dest User
copier.CopyWithOption(&dest, src, copier.Option{DeepCopy: true}) // 复制切片内容而非指针

典型应用场景

  • DTO 转换:将数据库模型(Model)转换为 API 响应体(DTO)或前端所需的 JSON 结构。
  • 配置覆盖:合并默认配置和用户自定义配置,忽略敏感字段。
  • 微服务通信:不同服务间消息结构的转换,如 gRPC 消息 ↔ 内部结构体。
  • 测试数据构造:快速生成测试对象的变体,避免重复初始化逻辑。

实战示例

场景:API 响应过滤敏感字段

代码语言:javascript
复制
type UserModel struct {
    ID       int
    Email    string
    Password string
}

type UserResponse struct {
    ID    int`json:"id"`
    Email string`json:"email"`
// Password 字段被排除
}

funcGetUser(ctx *gin.Context) {
    user := getUserFromDB() // 获取数据库模型
var resp UserResponse
    copier.Copy(&resp, &user) // 自动复制 ID 和 Email,跳过 Password
    ctx.JSON(200, resp)
}

总结

copier 是处理 Go 结构体复制的神器,尤其适合需要频繁进行数据转换的场景。尽管反射带来轻微性能损耗,但其带来的代码简洁性和可维护性提升,在大多数项目中利大于弊。推荐在 Web 开发、微服务架构或任何涉及多数据模型转换的项目中尝试使用。

引用链接

[1]copier: https://github.com/jinzhu/copier

[2]GORM: https://github.com/go-gorm/gorm

<<相关阅读>>

每日一库:Excelize——Go语言高效处理Excel的利器

每日一库:ImGo —— 简洁链式调用的 Go 图像处理库

每日一库:Google UUID(Go语言实现)

每日一库:cron - Go 高性能定时任务库

每日一库:Ants —— 高性能低损耗的 Goroutine

每日一库:now —— Go 语言时间处理工具库

每日一库:go-astisub —— 专注于多格式字幕文件的处理

每日一库:retry-go —— Go 语言轻量级重试库

每日一库:Govalidator —— Go 语言的强大验证与清理工具

每日一库:Expr - Go 语言的高性能动态表达式引擎

每日一库:Uber 开源的 Go 依赖注入库 dig

每日一库:Lancet —— Go 语言高效工具库

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-05-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 七点一刻的魔法书 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 核心功能
  • 典型应用场景
  • 实战示例
  • 总结
    • 引用链接
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档