zoukankan      html  css  js  c++  java
  • golang struct 转map 及 map[string]*Struct 初始化和遍历

    package main
    
    import (
    	"encoding/json"
    	"errors"
    	"fmt"
    	"reflect"
    	"strconv"
    	"time"
    )
    
    type User struct {
    	a string
    	b string
    }
    
    type S struct {
    	User
    	Name    string
    	Age     int
    	Address string
    }
    
    //结构体转map方法1
    func Struct2Map(obj interface{}) map[string]interface{} {
    	t := reflect.TypeOf(obj)
    	v := reflect.ValueOf(obj)
    
    	var data = make(map[string]interface{})
    	//func (v Value) NumField() int,  返回v持有的结构体类型值的字段数,如果v的Kind不是Struct会panic
    	for i := 0; i < t.NumField(); i++ {
    		data[t.Field(i).Name] = v.Field(i).Interface()
    	}
    	return data
    }
    
    //结构体转map方法2
    func StructToMapViaJson(data S) map[string]interface{} {
    	m := make(map[string]interface{})
    	//struct 转json
    	j, _ := json.Marshal(data)
    	//json 转map
    	json.Unmarshal(j, &m)
    	return m
    }
    
    func FillStruct(data map[string]interface{}, obj interface{}) error {
    	for k, v := range data {
    		//fmt.Println("k: ", k, " v: ", v)
    		err := SetField(obj, k, v)
    		if err != nil {
    			return err
    		}
    	}
    	return nil
    }
    
    func SetField(obj interface{}, k string, v interface{}) error {
    	//结构体属性值
    	structValue := reflect.ValueOf(obj).Elem()
    	//fmt.Println("structValue: ", structValue)
    	//结构体单个属性值
    	structFieldValue := structValue.FieldByName(k)
    	//fmt.Println("structFieldValue: ", structFieldValue)
    	if !structFieldValue.IsValid() {
    		return fmt.Errorf("No such field: %s in obj", k)
    	}
    	if !structFieldValue.CanSet() {
    		return fmt.Errorf("Cannot set %s field value", k)
    	}
    	//结构体属性类型
    	structFieldType := structFieldValue.Type()
    	val := reflect.ValueOf(v)
    	var err error
    	if structFieldType != val.Type() {
    		//类型转换
    		val, err = TypeConversion(fmt.Sprintf("%v", v), structFieldValue.Type().Name())
    		if err != nil {
    			return err
    		}
    	}
    	structFieldValue.Set(val)
    	return nil
    }
    
    func TypeConversion(value string, ntype string) (reflect.Value, error) {
    	fmt.Println("call TypeConversion...")
    	if ntype == "string" {
    		return reflect.ValueOf(value), nil
    	} else if ntype == "time.Time" {
    		t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
    		return reflect.ValueOf(t), err
    	} else if ntype == "Time" {
    		t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
    		return reflect.ValueOf(t), err
    	} else if ntype == "int" {
    		i, err := strconv.Atoi(value)
    		return reflect.ValueOf(i), err
    	} else if ntype == "int8" {
    		i, err := strconv.ParseInt(value, 10, 64)
    		return reflect.ValueOf(int8(i)), err
    	} else if ntype == "int32" {
    		i, err := strconv.ParseInt(value, 10, 64)
    		return reflect.ValueOf(int64(i)), err
    	} else if ntype == "int64" {
    		i, err := strconv.ParseInt(value, 10, 64)
    		return reflect.ValueOf(i), err
    	} else if ntype == "float32" {
    		i, err := strconv.ParseFloat(value, 64)
    		return reflect.ValueOf(float32(i)), err
    	} else if ntype == "float64" {
    		i, err := strconv.ParseFloat(value, 64)
    		return reflect.ValueOf(i), err
    	}
    
    	//else if .......增加其他一些类型的转换
    
    	return reflect.ValueOf(value), errors.New("未知的类型:" + ntype)
    }
    
    func main() {
    
    	var s S
    	Types := reflect.TypeOf(s)
    	//TypeData.FieldByIndex([]int{}) 返回 StructField
    	//[]int{}参数: 第一个是struct类型的索引(如果索引为参数一的数据类型不是struct会报错), 第二个是索引为参数一的结构体内属性的索引
    	//例如[]int{0,0} 会输出[0] a string,表示索引为0的结构体User内索引为0的数据是a
    	//[]int{0, 1} 会输出[1] b string
    	//[]int{1, 0}会报错, 因为索引为1的数据是S结构体中的数据 Name string,数据类型不是struct
    	res := Types.FieldByIndex([]int{0, 0})
    	fmt.Println("FieldByIndex: ", res.Index, res.Name, res.Type)
    
    	//struct to map
    	info := S{Name: "xsk", Age: 22, Address: "shanghai"}
    	data := Struct2Map(info)
    	fmt.Println("data: ", data, "  ", "typeof(data): ", reflect.TypeOf(data))
    	for k, v := range data {
    		fmt.Println(k, v.(interface{}))
    	}
    	fmt.Println("---------")
    	data1 := StructToMapViaJson(info)
    	fmt.Println("data1: ", data1, "  ", "typeof(data1): ", reflect.TypeOf(data1))
    	for k, v := range data1 {
    		fmt.Println(k, v.(interface{}))
    	}
    	fmt.Println("---------")
    
    	//map to struct
    	data2 := make(map[string]interface{})
    	data2["Name"] = "xsk"
    	data2["Age"] = 22
    	data2["Address"] = "shanghai"
    	result := &S{}
    	err := FillStruct(data2, result)
    	fmt.Println("err: ", err, " result: ", fmt.Sprintf("%+v", *result))
    	fmt.Println("---------")
    
    	//map[string]*Struct 下面几种初始化都行
    	//第一种
    	//var info1 = map[string]*S{"info": &S{Name: "mtt", Age: 23, Address: "shanghai"}}
    	//第二种
    	var info1 = map[string]*S{"info": &S{}, "other": &S{}}
    	info1["info"].Name = "mtt"
    	info1["info"].Age = 23
    	info1["info"].Address = "shanghai"
    
    	fmt.Println("info1: ", *info1["info"])
    	t := reflect.TypeOf(*info1["info"])
    	v := reflect.ValueOf(*info1["info"])
    	for k := 0; k < t.NumField(); k++ {
    		fmt.Printf("%s: %v
    ", t.Field(k).Name, v.Field(k).Interface())
    	}
    	fmt.Println("---------")
    
    	//第三种
    	var info2 = map[string]*S{}
    	info2["info"] = &S{Name: "xly", Age: 1, Address: "shanghai"}
    	fmt.Println("info2: ", *info2["info"])
    	ty := reflect.TypeOf(*info2["info"])
    	vl := reflect.ValueOf(*info2["info"])
    	for k := 0; k < ty.NumField(); k++ {
    		fmt.Printf("%s: %v
    ", ty.Field(k).Name, vl.Field(k).Interface())
    	}
    
    }
    

    golang 中 map 转 struct

    package main
    
    import (
    	"fmt"
    	"github.com/goinggo/mapstructure"
    )
    
    type Person struct {
        Name string
        Age int
    }
    
    func MapToStruct() {
    	mapInstance := make(map[string]interface{})
    	mapInstance["Name"] = "liang637210"
    	mapInstance["Age"] = 28
    
    	var person Person
    	//将 map 转换为指定的结构体
    	if err := mapstructure.Decode(mapInstance, &person); err != nil {
    		fmt.Println(err)
    	}
    	fmt.Printf("map2struct后得到的 struct 内容为:%v", person)
    }
    
    func main(){
    	MapToStruct()
    }
    
  • 相关阅读:
    按钮UIButton内图片和文字位置的设置(两种方式)
    关于Xcode上的Other linker flags基本介绍
    GCD定时器
    线程间的通信(3种方式)
    scrollView中内部控件的悬停
    十七:字符串文件的读写
    十六:NSString的创建以及相关细节
    十五:NSValue
    react生命周期遇到的问题
    笔记----深入浅出《React和Redux》第四章
  • 原文地址:https://www.cnblogs.com/nyist-xsk/p/11301468.html
Copyright © 2011-2022 走看看