Skip to content
鼓励作者:欢迎打赏犒劳

go对象拷贝

工具类

go
// Package beanutil 提供类似 Java BeanUtils 的结构体拷贝功能
// 使用 github.com/jinzhu/copier 作为底层引擎,支持自动类型转换、slice 批量拷贝等
package utils

import (
	"fmt"
	"reflect"

	"github.com/jinzhu/copier"
)

// CopyProperties 将源对象的属性复制到目标对象。
//
// 参数:
//   - target: 目标对象的指针(必须是指针)
//   - source: 源对象(可以是指针或值,支持结构体、slice 等)
//
// 示例:
//
//	var dto UserDTO
//	err := beanutil.CopyProperties(&dto, user)
//
//	var dtos []UserDTO
//	err := beanutil.CopyProperties(&dtos, users)
func CopyProperties(target, source interface{}) error {
	if source == nil {
		return fmt.Errorf("beanutil.CopyProperties: source cannot be nil")
	}
	if target == nil {
		return fmt.Errorf("beanutil.CopyProperties: target cannot be nil")
	}
	if reflect.TypeOf(target).Kind() != reflect.Ptr {
		return fmt.Errorf("beanutil.CopyProperties: target must be a pointer")
	}

	err := copier.Copy(target, source)
	if err != nil {
		return fmt.Errorf("beanutil.CopyProperties: copy failed: %w", err)
	}

	return nil
}

// CopyPropertiesOrPanic 与 CopyProperties 相同,但在出错时 panic
func CopyPropertiesOrPanic(target, source interface{}) {
	if err := CopyProperties(target, source); err != nil {
		panic(err)
	}
}

main.go

go
package main

import (
	"demo/utils"
	"fmt"
)

type User struct {
	Name string
	Age  int
	Tags []string
}

type UserDTO struct {
	Name  string
	Age   int32
	Tags  []string
	Extra string // 自动忽略
}

func main() {
	// 示例1:单个对象拷贝
	user := User{
		Name: "Alice",
		Age:  30,
		Tags: []string{"go", "dev"},
	}

	var dto UserDTO
	err := utils.CopyProperties(&dto, user) // 源可以是值
	if err != nil {
		fmt.Println("Copy failed:", err)
		return
	}
	fmt.Printf("User -> DTO: %+v\n", dto)

	// 示例2:Slice 拷贝
	users := []User{
		{Name: "Bob", Age: 25, Tags: []string{"frontend"}},
		{Name: "Charlie", Age: 35, Tags: []string{"backend", "rust"}},
	}

	var dtos []UserDTO
	err = utils.CopyProperties(&dtos, users)
	if err != nil {
		fmt.Println("Copy slice failed:", err)
		return
	}
	fmt.Printf("Users -> DTOS: %+v\n", dtos)

	// 示例3:panic 版本(用于初始化等可信场景)
	var dto2 UserDTO
	utils.CopyPropertiesOrPanic(&dto2, &user)
	fmt.Printf("DTO2: %+v\n", dto2)
}

结果

text
User -> DTO: {Name:Alice Age:30 Tags:[go dev] Extra:}
Users -> DTOS: [{Name:Bob Age:25 Tags:[frontend] Extra:} {Name:Charlie Age:35 Tags:[backend rust] Extra:}]
DTO2: {Name:Alice Age:30 Tags:[go dev] Extra:}

如有转载或 CV 的请标注本站原文地址