Go Struct Map切片 等之间的拷贝

Posted jiangxiaoju

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go Struct Map切片 等之间的拷贝相关的知识,希望对你有一定的参考价值。

原创不易,未经允许,请勿转载。

在写接口时,常常遇到这种情况,需要把某个struct对象转成另一个struct对象,但这两个struct之间,仅struct名不同而已,但是属性名基本都是一致的。
例如需要把User对象转成UserResp的对象。又或者需要进行Map、切片之间的拷贝。如果采用手动复制的话,会增加很多重复性的无用工作。

type User struct 
 	Username string
    Password string


type UserResp struct 
    Username string
    Password string

有两种办法可以解决
第一种就是通过json序列化的形式,先把原对象序列化成json数据化,在反序列化到目标对象上。
实现代码如下

// 把orgin的值通过json tag赋值给target
// target要为指针类型
func SwapEntity(origin, target interface) (err error) 
	dataByte, err := json.Marshal(origin)
	if err != nil 
		return
	
	return json.Unmarshal(dataByte, target)


第二种方法就是借助第三方库。
https://github.dev/jinzhu/copier
这是gorm作者开源的另一个工具库,可以实现两个对象之间的拷贝。
具有以下特性

  • Copy from field to field with same name
  • Copy from method to field with same name
  • Copy from field to method with same name
  • Copy from slice to slice
  • Copy from struct to slice
  • Copy from map to map
  • Enforce copying a field with a tag
  • Ignore a field with a tag
  • Deep Copy

安装方式
go get github.com/jinzhu/copier

下面这是官方提供的实例代码。

package main

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

type User struct 
	Name        string
	Role        string
	Age         int32
	EmployeCode int64 `copier:"EmployeNum"` // specify field name

	// Explicitly ignored in the destination struct.
	Salary   int


func (user *User) DoubleAge() int32 
	return 2 * user.Age


// Tags in the destination Struct provide instructions to copier.Copy to ignore
// or enforce copying and to panic or return an error if a field was not copied.
type Employee 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.
	Age       int32  `copier:"must,nopanic"`

	// Tell copier.Copy to explicitly ignore copying this field.
	Salary    int    `copier:"-"`

	DoubleAge int32
	EmployeId int64 `copier:"EmployeNum"` // specify field name
	SuperRole string


func (employee *Employee) Role(role string) 
	employee.SuperRole = "Super " + role


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

	copier.Copy(&employee, &user)

	fmt.Printf("%#v \\n", employee)
	// Employee
	//    Name: "Jinzhu",           // Copy from field
	//    Age: 18,                  // Copy from field
	//    Salary:150000,            // Copying explicitly ignored
	//    DoubleAge: 36,            // Copy from method
	//    EmployeeId: 0,            // Ignored
	//    SuperRole: "Super Admin", // Copy to method
	// 

	// Copy struct to slice
	copier.Copy(&employees, &user)

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

	// Copy slice to slice
	employees = []Employee
	copier.Copy(&employees, &users)

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

 	// Copy map to map
	map1 := map[int]int3: 6, 4: 8
	map2 := map[int32]int8
	copier.Copy(&map2, map1)

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

如果这篇文章对您有所帮助,麻烦点个一键三连。

原创不易,未经允许,请勿转载。

博客主页:https://xiaojujiang.blog.csdn.net/

以上是关于Go Struct Map切片 等之间的拷贝的主要内容,如果未能解决你的问题,请参考以下文章

Go Struct Map切片 等之间的拷贝

Go Struct Map切片 等之间的拷贝

Golang 基础:Go Module, for range, 切片, map, struct 等使用和实现

Golang 基础:Go Module, for range, 切片, map, struct 等使用和实现

Golang 入门总结:Go Module, for range, 切片, map, struct 等使用和实现

Golang 入门总结:Go Module, for range, 切片, map, struct 等使用和实现