golang struct 转map 及 map[string]*Struct 初始化和遍历
生活随笔
收集整理的這篇文章主要介紹了
golang struct 转map 及 map[string]*Struct 初始化和遍历
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
package mainimport ("encoding/json""errors""fmt""reflect""strconv""time"
)type User struct {a stringb string
}type S struct {UserName stringAge intAddress 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會panicfor 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 轉jsonj, _ := json.Marshal(data)//json 轉mapjson.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 errorif 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 STypes := 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,數據類型不是structres := Types.FieldByIndex([]int{0, 0})fmt.Println("FieldByIndex: ", res.Index, res.Name, res.Type)//struct to mapinfo := 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 structdata2 := make(map[string]interface{})data2["Name"] = "xsk"data2["Age"] = 22data2["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 = 23info1["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\n", 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\n", ty.Field(k).Name, vl.Field(k).Interface())}}
golang 中 map 轉 struct
package mainimport ("fmt""github.com/goinggo/mapstructure" )type Person struct {Name stringAge int }func MapToStruct() {mapInstance := make(map[string]interface{})mapInstance["Name"] = "liang637210"mapInstance["Age"] = 28var person Person//將 map 轉換為指定的結構體if err := mapstructure.Decode(mapInstance, &person); err != nil {fmt.Println(err)}fmt.Printf("map2struct后得到的 struct 內容為:%v", person) }func main(){MapToStruct() }轉載于:https://www.cnblogs.com/nyist-xsk/p/11301468.html
總結
以上是生活随笔為你收集整理的golang struct 转map 及 map[string]*Struct 初始化和遍历的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛谷P1962 斐波那契数列题解
- 下一篇: 富文本器的选择