内容简介:感谢顺带一提,作者是国人
简介
上一篇文章 介绍了 mergo
库的使用, mergo
是用来给结构体或 map
赋值的。 mergo
有一个明显的不足——它只能处理相同类型的结构!如果类型不同,即使字段名和类型完全相同, mergo
也无能为力。今天我们要介绍的 copier
库就能处理不同类型之间的赋值。除此之外, copier
还能:
- 调用同名方法为字段赋值;
- 以源对象字段为参数调用目标对象的方法,从而为目标对象赋值(当然也可以做其它的任何事情);
- 将切片赋值给切片(可以是不同类型哦);
- 将结构体追加到切片中。
感谢 @thinkgos 推荐。
顺带一提,作者是国人 jinzhu 大佬,如果你想找一个 Go 语言的 ORM 库, gorm 你值得拥有!
快速使用
先安装:
$ go get github.com/jinzhu/copier
后使用:
package main import ( "fmt" "github.com/jinzhu/copier" ) type User struct { Name string Age int } type Employee struct { Name string Age int Role string } func main() { user := User{Name: "dj", Age: 18} employee := Employee{} copier.Copy(&employee, &user) fmt.Printf("%#v\n", employee) }
很好理解,就是将 user
对象中的字段赋值到 employee
的同名字段中。如果目标对象中没有同名的字段,则该字段被忽略。
高级特性
方法赋值
目标对象中的一些字段,源对象中没有,但是源对象有同名的方法。这时 Copy
会调用这个方法,将返回值赋值给目标对象中的字段:
type User struct { Name string Age int } func (u *User) DoubleAge() int { return 2 * u.Age } type Employee struct { Name string DoubleAge int Role string } func main() { user := User{Name: "dj", Age: 18} employee := Employee{} copier.Copy(&employee, &user) fmt.Printf("%#v\n", employee) }
我们给 User
添加一个 DoubleAge
方法。 Employee
结构有字段 DoubleAge
, User
中没有,但是 User
有一个同名的方法,这时 Copy
调用 user
的 DoubleAge
方法为 employee
的 DoubleAge
赋值,得到 36。
调用目标方法
有时候源对象中的某个字段没有出现在目标对象中,但是目标对象有一个同名的方法,方法接受一个同类型的参数,这时 Copy
会以源对象的这个字段作为参数调用目标对象的该方法:
type User struct { Name string Age int Role string } type Employee struct { Name string Age int SuperRole string } func (e *Employee) Role(role string) { e.SuperRole = "Super" + role } func main() { user := User{Name: "dj", Age: 18, Role: "Admin"} employee := Employee{} copier.Copy(&employee, &user) fmt.Printf("%#v\n", employee) }
我们给 Employee
添加了一个 Role
方法, User
的字段 Role
没有出现在 Employee
中,但是 Employee
有一个同名方法。 Copy
函数内部会以 user
对象的 Role
字段为参数调用 employee
的 Role
方法。最终,我们的 employee
对象的 SuperRole
值变为 SuperAdmin
。实际上,这个方法中可以执行任何操作,不一定是赋值。
切片赋值
使用一个切片来为另一个切片赋值。如果类型相同,那好办,直接 append
就行。如果类型不同呢? copier
就派上大用场了:
type User struct { Name string Age int } type Employee struct { Name string Age int Role string } func main() { users := []User{ {Name: "dj", Age: 18}, {Name: "dj2", Age: 18}, } employees := []Employee{} copier.Copy(&employees, &users) fmt.Printf("%#v\n", employees) }
这个实际上就是将源切片中每个元素分别赋值到目标切片中。
将结构赋值到切片
这个不难,实际上就是根据源对象生成一个和目标切片类型相符合的对象,然后 append
到目标切片中:
type User struct { Name string Age int } type Employee struct { Name string Age int Role string } func main() { user := User{Name: "dj", Age: 18} employees := []Employee{} copier.Copy(&employees, &user) fmt.Printf("%#v\n", employees) }
上面代码中, Copy
先通过 user
生成一个 Employee
对象,然后 append
到切片 employees
中。
汇总
最后将所有的特性汇总在一个例子中,其实就是 Copier
的 GitHub 仓库首页的例子:
type User struct { Name string Age int Role string } func (u *User) DoubleAge() int { return u.Age * 2 } type Employee struct { Name string Age int SuperRole string } func (e *Employee) Role(role string) { e.SuperRole = "Super" + role } func main() { var ( user = User{Name: "dj", Age: 18} users = []User{ {Name: "dj", Age: 18, Role: "Admin"}, {Name: "dj2", Age: 18, Role: "Dev"}, } employee = Employee{} employees = []Employee{} ) copier.Copy(&employee, &user) fmt.Printf("%#v\n", employee) copier.Copy(&employees, &user) fmt.Printf("%#v\n", employees) // employees = []Employee{} copier.Copy(&employees, &users) fmt.Printf("%#v\n", employees) }
上面例子中,我故意把 employees = []Employee{}
这一行注释掉,最后输出的 employees
是 3 个元素,能更清楚的看出切片到切片是 append
的,目标切片原来的元素还是保留的。
总结
copier
库的代码量很小,用了不到 200 行的代码就实现了如此实用的一个功能,非常值得一看!
大家如果发现好玩、好用的 Go 语言库,欢迎到 Go 每日一库 GitHub 上提交 issue:smile:
参考
- copier GitHub: https://github.com/jinzhu/copier
- Go 每日一库 GitHub: https://github.com/darjun/go-daily-lib
我
欢迎关注我的微信公众号【GoUpUp】,共同学习,一起进步~
以上所述就是小编给大家介绍的《Go 每日一库之 copier》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
阿里巴巴正传:我们与马云的“一步之遥”
方兴东、刘伟 / 江苏凤凰文艺出版社 / 2015-1 / 45.00
十几年来,方兴东与马云每年一次,老友聚首,开怀畅谈,阿里上市前,作者再次与马云深度对话,阿里上市前的布局,深入探讨了一系列人们关心的话题。 本书忠实记录了阿里壮大、马云封圣的历史。作者通过细致梳理和盘点,对阿里巴巴的15年成长史进行了忠实回顾。从海博翻译社到淘宝网,从淘宝商城到天猫,从支付宝到阿里云计算,从拉来软银的第一笔投资到纽交所上市,作者对其中涉及到的人物、细节都有生动展现;对于马云、......一起来看看 《阿里巴巴正传:我们与马云的“一步之遥”》 这本书的介绍吧!