copier:万能的对象拷贝偷懒神器

copier:万能的对象拷贝偷懒神器

如果你干什么事

都专注一点

那么你就会超过80%

的人

如果你在一个点上

坚持5年

那么你进入10%

都有可能

 

我见过的最美的一天

是你穿过人群找到我

的那一天

 

golang学习记
分享golang 学习的点滴
115篇原创内容

今天推荐一个结构体之间拷贝属性的库,copier。

结构体之间复制一个结构体的属性值到另一个结构体,这类需求是很常见的。

比如你从数据库里查询出来一个用户实体类,一般来说,在一个接口里只需要其中一部分信息,然后返回这部分信息给前端。

由于前端的发现非常迅猛,出现了很多的新兴技术,从最早的web,使用到JavaScript ,再到现在的H5,小程序,包括微信小程序,抖音小程序,支付宝小程序,安卓,苹果,以及实现多平台的flutter ,Kotlin,uniapp 。

针对不同的端,也可能有不同的数据显示要求。

所以快速实现对象之间的属性复制是很重要的。

开始使用

第一步,引入copier

go get github.com/jinzhu/copier

 

你没看错,这个库又是由jinzhu 大佬开发的,真是越优秀的人越努力。

第二步,初使用

package main

import (
"fmt"
"github.com/jinzhu/copier"
)

type User struct {
Name string
Role string
Age int32

// 等会复制的时候会忽略这个属性
Salary int
}

 

目标对象

type DestUser struct {
// Tell copier.Copy to panic if this field is not copied.
Name string `copier:"must"`

// Tell copier.Copy to return an error if this field is not copied.
// 如果这个字段没有被复制 会返回一个error
Age int32 `copier:"must,nopanic"`

// 配置 不复制这个属性
Salary int `copier:"-"`


}

 

开始复制

func main() {
var (
user = User{Name: "Jinzhu", Age: 18, Role: "Admin", Salary: 200000}
users = []User{{Name: "Jinzhu", Age: 18, Role: "Admin", Salary: 100000}, {Name: "jinzhu 2", Age: 30, Role: "Dev", Salary: 60000}}
employee = DestUser{Salary: 150000}
employees = []DestUser{}
)

copier.Copy(&employee, &user)

fmt.Printf("%#v \n", employee)
// 打印结果如下
// Employee{
// Name: "Jinzhu",
// Age: 18,
// Salary:150000, // 被忽略了 还是原来的值

// }

// 把单个对象复制为一个切片,毕竟切片
// 很灵活
copier.Copy(&employees, &user)

fmt.Printf("%#v \n", employees)
// []Employee{
// {Name: "Jinzhu", Age: 18, Salary:0, DoubleAge: 36, EmployeeId: 0, SuperRole: "Super Admin"}
// }

// 从一个切片 到 另一个切片
employees = []Employee{}
copier.Copy(&employees, &users)

fmt.Printf("%#v \n", employees)
// []Employee{
// {Name: "Jinzhu", Age: 18, Salary:0, DoubleAge: 36, EmployeeId: 0, SuperRole: "Super Admin"},
// {Name: "jinzhu 2", Age: 30, Salary:0, DoubleAge: 60, EmployeeId: 0, SuperRole: "Super Dev"},
// }

// map 之间的复制
// 很多时候对象的另一种表现方式就是map
map1 := map[int]int{3: 6, 4: 8}
map2 := map[int32]int8{}
copier.Copy(&map2, map1)

fmt.Printf("%#v \n", map2)
// map[int32]int8{3:6, 4:8}
}

 

高级使用

CopyWithOption 函数可以进一步的控制复制的行为。

IgnoreEmpty :设置为true 表示复制的时候不会复制是0值的字段,从而加快复制速度

DeepCopy :设置为true 表示支持深拷贝

Converters :用来做类型转换的,比如把原对象里面的time 类型的字段转换成目标对象的字符串类型的时间格式。

以上三点中的前两点都是比较常用的,知道了这个神器,大家就不要去写一大堆Set方法啦,用一行代码能搞定的一定不要多写bug哦。

 

golang 学习记
golang · 目录
上一篇golang新一代格式化工具(更强的代码洁癖),gofmt可以退休了
阅读 30
 
 
 
 
 
 
 
 
posted @ 2024-04-07 10:42  技术颜良  阅读(701)  评论(0)    收藏  举报