golang之copier
今天我们要介绍的copier
库就能处理不同类型之间的赋值。除此之外,copier
还能:
- 调用同名方法为字段赋值;
- 以源对象字段为参数调用目标对象的方法,从而为目标对象赋值(当然也可以做其它的任何事情);
- 将切片赋值给切片(可以是不同类型哦);
- 将结构体追加到切片中。
快速使用
先安装:
$ 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
的,目标切片原来的元素还是保留的。
golang之copier的更多相关文章
- Golang, 以17个简短代码片段,切底弄懂 channel 基础
(原创出处为本博客:http://www.cnblogs.com/linguanh/) 前序: 因为打算自己搞个基于Golang的IM服务器,所以复习了下之前一直没怎么使用的协程.管道等高并发编程知识 ...
- 说说Golang的使用心得
13年上半年接触了Golang,对Golang十分喜爱.现在是2015年,离春节还有几天,从开始学习到现在的一年半时间里,前前后后也用Golang写了些代码,其中包括业余时间的,也有产品项目中的.一直 ...
- TODO:Golang指针使用注意事项
TODO:Golang指针使用注意事项 先来看简单的例子1: 输出: 1 1 例子2: 输出: 1 3 例子1是使用值传递,Add方法不会做任何改变:例子2是使用指针传递,会改变地址,从而改变地址. ...
- Golang 编写的图片压缩程序,质量、尺寸压缩,批量、单张压缩
目录: 前序 效果图 简介 全部代码 前序: 接触 golang 不久,一直是边学边做,边总结,深深感到这门语言的魅力,等下要跟大家分享是最近项目 服务端 用到的图片压缩程序,我单独分离了出来,做成了 ...
- golang struct扩展函数参数命名警告
今天在使用VSCode编写golang代码时,定义一个struct,扩展几个方法,如下: package storage import ( "fmt" "github.c ...
- golang语言构造函数
1.构造函数定义 构造函数 ,是一种特殊的方法.主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中.特别的一个类可以有多个构造函数 ,可根据其参数个 ...
- TODO:Golang语言TCP/UDP协议重用地址端口
TODO:Golang语言TCP/UDP协议重用地址端口 这是一个简单的包来解决重用地址的问题. go net包(据我所知)不允许设置套接字选项. 这在尝试进行TCP NAT时尤其成问题,其需要在同一 ...
- golang的安装
整理了一下,网上关于golang的安装有三种方式(注明一下,我的环境为CentOS-6.x, 64bit) 方式一:yum安装(最简单) rpm -Uvh http://dl.fedoraprojec ...
- golang枚举类型 - iota用法拾遗
在c#.java等高级语言中,经常会用到枚举类型来表示状态等.在golang中并没有枚举类型,如何实现枚举呢?首先从枚举的概念入手. 1.枚举类型定义 从百度百科查询解释如下:http://baike ...
- golang 使用 iota
iota是golang语言的常量计数器,只能在常量的表达式中使用. iota在const关键字出现时将被重置为0(const内部的第一行之前),const中每新增一行常量声明将使iota计数一次(io ...
随机推荐
- CLion 2022.2.4破解教程详细图解mac,windows,linux均适用
下载与安装 此教程为CLion 2022.2.4 破解教程,且此教程以及下面提供的破解补丁适用与2022.2以后的新版本. 2022年11月10日亲测有效,mac与windows均测试完美破解 CLi ...
- 牛逼!Vue3.5的useTemplateRef让ref操作DOM更加丝滑
前言 vue3中想要访问DOM和子组件可以使用ref进行模版引用,但是这个ref有一些让人迷惑的地方.比如定义的ref变量到底是一个响应式数据还是DOM元素?还有template中ref属性的值明明是 ...
- 【转】ElasticSearch报错FORBIDDEN/12/index read-only / allow delete (api) ,read_only_allow_delete 设置 windows
仅供自己记录使用,原文链接:ElasticSearch报错FORBIDDEN/12/index read-only / allow delete (api)_sinat_22387459的博客-CSD ...
- Openstack-Train( 一)基础环境
openStack-train 搭建部署 当面对KVM集群的时候,我们对KVM的管理以及宿主机的管理就会遇到很大的难度,例如: 查看每一个宿主机有多少台KVM虚拟机? 查看每一个宿主机资源信息,每一个 ...
- Asp.net Core 学习笔记 Azure Storage
更新: 2021-07-22 使用 Azure storage 以后, 还要解决一个 url 的问题. 文件自然是通过我们的 domain 来访问才合理丫. 这个是 azure 的 url : htt ...
- Soring —— 容器总结
获取bean 容器层次结构图 *BeanFactory 是IoC容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载 bean相关 依赖注入相关
- 彻底理解 IP 地址,子网掩码,子网划分
原文地址:https://oldme.net/article/55彻底理解 IP 地址,子网掩码,子网划分 什么是 IP 协议 在回答什么是 IP 协议前,我们先需要回答另外一个问题:什么是网络?从普 ...
- 阿里邮箱网页正常登陆,outlook报错
事件起因: 某客户使用阿里邮箱办公,然又使用outlook绑定阿里邮箱:在网页端可以登录阿里邮箱,但是在outlook的登录的时候,服务器.端口均设置无误,但是就是登录不上去,死活都等登录不上去,总是 ...
- 从SQL Server过渡到PostgreSQL:理解模式的差异
从SQL Server过渡到PostgreSQL:理解模式的差异 前言 随着越来越多的企业转向开源技术,商业数据库管理员和开发者也逐渐面临向PostgreSQL迁移的需求. 虽然SQL Server和 ...
- 轨道控制器 threejs
就是一个可以360转动的相机,通过不断的改变相机的参数 然后渲染达到效果. // 引入相机控件 -- 轨道控制器 // console.log('OrbitControls',OrbitContro ...