结构体转map[string]interface{}方式

结构体转map[string]interface{}的若干方法

1.JSON序列化方式

  • 先用JSON序列化,再反序列化转成map:

    package main
    
    import (
    	"encoding/json"
    	"fmt"
    )
    type UserInfo struct {
    	Name string `json:"name"`
    	Age int `json:"age"`
    }
    
    
    func main (){
    	u1 := UserInfo{Name:"xujunkai", Age:20}
    	fmt.Printf("%T
    ", u1)// main.UserInfo
    	var mp map[string]interface{}
    	// byte_u1为byte类型切片
    	byte_u1, _ := json.Marshal(&u1)
    	fmt.Printf("%T
    ", byte_u1)
    	_ = json.Unmarshal(byte_u1, &mp)
    	fmt.Println(mp)// map[name:xujunkai age:20]
        
        for k,v := range(mp) {
    		fmt.Printf("key:%v  value:%v
    ", k, v)
    	}
        // key:name  value:xujunkai
    	// key:age  value:20
    }
    
    

2. 反射方法

  • 通过反射遍历结构体字段方式生成map

    package main
    import (
    	"fmt"
    	"reflect"
    )
    type UserInfo struct {
    	Name string `json:"name"`
    	Age int `json:"age"`
    }
    
    func reflexToMap(in interface{}, tagName string) (map[string]interface{},error) {
    	out := make(map[string]interface{})
    	// 获取 in的值对象
    	v := reflect.ValueOf(in)
    	fmt.Println("v:", v)
    	fmt.Println("v的类型为:", v.Kind())// ptr  指针类型
    	// 判断当前值对象是否为指针类型
    	if v.Kind() == reflect.Ptr {
    		// 通过v.Elem获取值指向元素的值
    		fmt.Println(v.Elem())// {xujunkai 20}
    		v = v.Elem()
    	}
    	fmt.Println(v.Kind()) // struct
    	// 判断类型不为结构体报错
    	if v.Kind() != reflect.Struct {
    		return nil, fmt.Errorf("not struct")
    	}
    
    	t := v.Type()
    	fmt.Println(t)
    	// 遍历结构体字段,指定tagName值,为map中key,字段值为map中value
    	for i:= 0; i < v.NumField(); i++ {
    		fi := t.Field(i)
    		fmt.Println("fi:", fi)
    		if tagValue := fi.Tag.Get(tagName); tagValue != "" {
    			out[tagValue] = v.Field(i).Interface()
    		}
    	}
    	return out, nil
    }
    func main (){
    	u1 := UserInfo{Name:"xujunkai", Age:20}
    	m2, _ := reflexToMap(&u1,"json")
    	for k, v := range(m2) {
    		fmt.Printf("key:%v  value:%v
    ", k, v)
    	}
    }
    

3.第三方库

  • 下载

    go get github.com/fatih/structs
    
  • 示例:

    
    import (
    	"fmt"
    	"github.com/fatih/structs"
    )
    
    
    u1 := UserInfo{Name:"xujunkai", Age:20}
    m3 := structs.Map(&u1)
    fmt.Println(m3)
    

4.嵌套结构体转map[string]interface{}

  • structs本身支持嵌套结构体转map[string]interface{},遇到嵌套结构体它会转换为map[string]interface{}嵌套map[string]interface{}的模式

    package main
    
    import (
    	"fmt"
    	"github.com/fatih/structs"
    )
    
    type UserInfo struct {
    	Name string `json:"name" structs:"name"`
    	Age int `json:"age" structs:"age"`
    	Profile `json:"profile" structs:"profile"`
    }
    type Profile struct {
    	Hobby string `json:"hobby" structs:"hobby"`
    }
    func main (){
    	u1 := UserInfo{Name:"xujunkai", Age: 18, Profile:Profile{Hobby:"swimming"}}
    	m3 := structs.Map(&u1)
    	fmt.Println(m3)
    	for k,v := range(m3) {
    		fmt.Printf("key:%s value:%v type:%T
    ",k,v,v)
    	}
    }
    
原文地址:https://www.cnblogs.com/xujunkai/p/13674528.html