cystructmap

package
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 27, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

deep_copy.go

utils.go

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func AnySliceToStructSlice

func AnySliceToStructSlice[T any](slice []interface{}, opts ...Option) ([]T, error)

InterfaceSliceToStructSlice 将 interface{} 切片(元素为 map)转换为结构体切片

func JsonBytesToStruct

func JsonBytesToStruct[T any](jsonBytes []byte, opts ...Option) (T, error)

JsonBytesToStruct 将 JSON []byte 转换为结构体。

参数:

  • jsonBytes: JSON []byte
  • opts: 可选的转换配置

返回值:

  • T: 转换后的结构体(可以是值或指针)
  • error: 如果转换失败返回错误

用法:

type User struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}
jsonBytes := []byte(`{"name": "John", "age": 30}`)
user, err := JsonBytesToStruct[User](jsonBytes)
// user = User{Name: "John", Age: 30}

特点:

  • 支持嵌套结构体
  • 支持指针字段
  • 自动类型转换
  • 支持自定义转换函数

局限:

  • 私有字段会被跳过
  • 标签为 "-" 的字段会被忽略

func JsonToStruct

func JsonToStruct[T any](jsonStr string, opts ...Option) (T, error)

JsonToStruct 将 JSON 字符串转换为结构体。

参数:

  • jsonStr: JSON 字符串
  • opts: 可选的转换配置

返回值:

  • T: 转换后的结构体(可以是值或指针)
  • error: 如果转换失败返回错误

用法:

type User struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}
jsonStr := `{"name": "John", "age": 30}`
user, err := JsonToStruct[User](jsonStr)
// user = User{Name: "John", Age: 30}

特点:

  • 支持嵌套结构体
  • 支持指针字段
  • 自动类型转换
  • 支持自定义转换函数

局限:

  • 私有字段会被跳过
  • 标签为 "-" 的字段会被忽略

func MapIntoStruct

func MapIntoStruct(m map[string]interface{}, out interface{}, opts ...Option) error

ScanIntoMap 将 map 映射到结构体指针(非泛型)。 out 必须是 *Struct;支持 Option 配置(tag、strict、convfunc、omitEmpty 等)。 MapIntoStruct 将 map 填充到结构体指针(非泛型)。 out 必须是 *Struct;支持 Option 配置(tag、strict、convfunc、omitEmpty 等)。

Example

示例用法

// 模拟从数据库或 API 获取的 map 数据,其中切片字段以 JSON 字符串形式存储
data := map[string]interface{}{
	"user_id": 123,
	"tags":    `["go", "programming", "json"]`, // JSON 字符串
	"scores":  `[95, 87, 92]`,                  // JSON 字符串
}

type User struct {
	UserID int      `json:"user_id"`
	Tags   []string `json:"tags"`
	Scores []int    `json:"scores"`
}

var user User
err := MapIntoStruct(data, &user)
if err != nil {
	fmt.Printf("Error: %v\n", err)
	return
}

fmt.Printf("User ID: %d\n", user.UserID)
fmt.Printf("Tags: %v\n", user.Tags)
fmt.Printf("Scores: %v\n", user.Scores)
Output:
User ID: 123
Tags: [go programming json]
Scores: [95 87 92]

func MapSliceToStructSlice

func MapSliceToStructSlice[T any](slice []map[string]interface{}, opts ...Option) ([]T, error)

MapSliceToStructSlice 将 map 切片转换为结构体切片

func MapToStruct

func MapToStruct[T any](m map[string]interface{}, opts ...Option) (T, error)

MapToStruct 将 Map 转换为结构体。

参数:

  • m: 源 Map
  • opts: 可选的转换配置

返回值:

  • T: 转换后的结构体(可以是值或指针)
  • error: 如果转换失败返回错误

用法:

type User struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}
m := map[string]interface{}{"name": "John", "age": 30}
user, err := MapToStruct[User](m)
// user = User{Name: "John", Age: 30}

特点:

  • 支持嵌套结构体
  • 支持指针字段
  • 自动类型转换
  • 支持自定义转换函数

局限:

  • 私有字段会被跳过
  • 标签为 "-" 的字段会被忽略

func MapsIntoStructSlice

func MapsIntoStructSlice(maps []map[string]interface{}, out interface{}, opts ...Option) error

MapsIntoStructSlice 将 map 列表填充到结构体切片指针(支持元素为 Struct 或 *Struct)。 out 必须是 *[]Struct 或 *[]*Struct。

func StructSliceToMapSlice

func StructSliceToMapSlice[T any](slice []T, opts ...Option) ([]map[string]any, error)

StructSliceToMapSlice 将结构体切片转换为 map 切片

func StructToMap

func StructToMap[T any](src T, opts ...Option) (map[string]interface{}, error)

StructToMap 将结构体转换为 Map。

参数:

  • src: 源结构体(可以是值或指针)
  • opts: 可选的转换配置

返回值:

  • map[string]interface{}: 转换后的 Map
  • error: 如果转换失败返回错误

用法:

type User struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}
user := User{Name: "John", Age: 30}
m, err := StructToMap(user)
// m = {"name": "John", "age": 30}

特点:

  • 支持嵌套结构体
  • 支持指针字段
  • 支持 omitempty 标签
  • 支持自定义转换函数

局限:

  • 私有字段会被跳过
  • 标签为 "-" 的字段会被忽略

func StructToStruct

func StructToStruct[S, T any](src *S, tar *T, opts ...Option) error

StructToStruct 将 *S 转换为 *T。 若底层结构体类型相同,则使用带缓存的深拷贝;否则通过 map 中转。

func WithContextOptions

func WithContextOptions(ctx context.Context, opts ...Option) context.Context

WithContextOptions 将反序列化选项存储到 context 中

Types

type FieldConvFunc

type FieldConvFunc func(field reflect.StructField, value reflect.Value) (any, bool)

FieldConvFunc 自定义字段转换函数

type MapStructConvConfig

type MapStructConvConfig struct {
	Tags               []string // 多个标签,按优先级顺序 fallback
	ConvFuncs          []FieldConvFunc
	OmitEmpty          bool // 全局是否忽略空值
	Strict             bool // 严格模式(默认 true),严格模式下类型必须完全匹配或可转换;非严格模式下尝试类型强转
	DisableTimeConvert bool // 禁用时间类型转换
	// contains filtered or unexported fields
}

MapStructConvConfig 转换配置

type Option

type Option func(*MapStructConvConfig)

Option 配置选项

func FromContext

func FromContext(ctx context.Context) []Option

FromContext 从 context 中获取反序列化选项

func WithComplexToJson

func WithComplexToJson() Option

WithComplexToJson 将复杂类型转换为 JSON 字符串

该选项会将以下类型序列化为 JSON 字符串:

  • 结构体(除了 time.Time)
  • 切片/数组
  • Map

使用场景:

  • 将嵌套结构体扁平化为 map 存储
  • 数据库列存储(将复杂对象存储为 JSON 字符串)
  • API 传输(将复杂对象序列化为字符串)
  • 日志记录(将复杂对象转换为字符串)

示例:

type User struct {
    ID    int      `json:"id"`
    Info  UserInfo `json:"info"`  // 嵌套结构体会被转换为 JSON 字符串
    Tags  []string `json:"tags"`  // 切片会被转换为 JSON 字符串
}

result, err := StructToMap(user, WithComplexToJson())
// result["info"] 会是 JSON 字符串: {"name":"Alice","age":30}
// result["tags"] 会是 JSON 字符串: ["tag1","tag2"]

func WithConvFunc

func WithConvFunc(fn ...FieldConvFunc) Option

WithConvFunc 添加自定义转换函数

func WithDisableTimeConvert

func WithDisableTimeConvert(disableTimeConvert bool) Option

func WithOmitEmpty

func WithOmitEmpty(omitEmpty bool) Option

WithOmitEmpty 设置全局是否忽略空值

func WithStrictMode

func WithStrictMode(strict bool) Option

WithNonStrict 启用非严格模式,允许类型转换(如 1 -> true)

func WithTag

func WithTag(tag string) Option

WithTag 指定单个 struct tag(如 json, mapstructure) 内部调用 WithTags,保持向后兼容

func WithTags

func WithTags(tags ...string) Option

WithTags 指定多个 struct tag,按优先级顺序 fallback 例如: WithTags("query", "form") 会先尝试 query 标签,如果不存在则尝试 form 标签

参数:

  • tags: 标签名称列表,按优先级从高到低排列

用法:

type Request struct {
    Page    int    `query:"page" form:"page"`
    Keyword string `query:"keyword"`
}
// 先尝试 query 标签,如果不存在则尝试 form 标签
err := MapIntoStruct(queryMap, &req, WithTags("query", "form"))

// 单标签用法(等同于 WithTag)
err := MapIntoStruct(queryMap, &req, WithTags("json"))

func WithTimeConvert

func WithTimeConvert(format ...string) Option

WithTimeConvert 支持时间类型的转换(两端必须至少有一个是 time.Time,含指针) 支持的转换:

  • time.Time <-> string (使用指定格式)
  • 数值类型 <-> time.Time (作为 Unix 时间戳)

注意: 数值 <-> string 不支持 (不需要 time.Time 中介,应使用其他方式转换) 支持指针类型的相互转换

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL