zoukankan      html  css  js  c++  java
  • 结构体转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)
      	}
      }
      
  • 相关阅读:
    Python pip – error: invalid command ‘bdist_wheel’
    css实现文字两端对齐(兼容所有浏览器)
    webpack中的require.context
    node 的path模块中 path.resolve()和path.join()的区别
    react-native项目中遇到的问题
    react-native针对android改变状态栏样式
    createBottomTabNavigator: 怎么在切换tab的时候让页面重新渲染
    当vue页面异步加载的数据想在页面上渲染怎么办
    git分布式版本控制系统
    $router和$route的区别,路由跳转方式name 、 path 和传参方式params 、query的区别
  • 原文地址:https://www.cnblogs.com/xujunkai/p/13674528.html
Copyright © 2011-2022 走看看