【go】【golang】想用反射做一个map数组转结构体数组的方法,代码如下,怎么把反射生成的结构体加进数组里?

描述

想做一个类似于orm的数据组件,遇到这个问题,把一个[]map[string]interface{}的response转换成对应类型的结构体数组里面

思路

看了orm的源码,以及网上的一些文章,然后用反射完成了单个结构体赋值,也就是orm中的err := o.Read(&user),做数组时参考了orm中的func (o *rawSet) QueryRows(containers ...interface{}) (int64, error)

相关代码

package test

import (

"errors"

"fmt"

"reflect"

"strings"

)

func MapToStruct() {

mList := []map[string]interface{}{

{"Id": 213, "Name": "zhaoliu", "Sex": "男"},

{"Id": 56, "Name": "zhangsan", "Sex": "男"},

{"Id": 7, "Name": "lisi", "Sex": "女"},

{"Id": 978, "Name": "wangwu", "Sex": "男"},

}

type User struct {

Id int

Name string

Sex string

}

users := []*User{}

mapToStruct(mList, &users)

fmt.Printf("users: %+v\n", users)

}

func mapToStruct(mList []map[string]interface{}, model interface{}) (err error) {

val := reflect.Indirect(reflect.ValueOf(model))

typ := val.Type()

fmt.Printf("val: %v\n", val)

fmt.Printf("typ: %v\n", typ)

for _, r := range mList {

mVal := reflect.Indirect(reflect.New(typ.Elem().Elem())).Addr()

//fmt.Printf("mVal: %+v\n", mVal)

for key, val := range r {

err = setField(mVal.Interface(), key, val)

if err != nil {

return err

}

}

//fmt.Printf("mVal: %+v\n", mVal)

val = reflect.Append(val, mVal)

}

fmt.Printf("val: %+v\n", val.Interface())

//model = val.Interface()

return err

}

//用map的值替换结构的值

func setField(obj interface{}, name string, value interface{}) error {

// 将首字母转换为大写

sl := strings.Split(name, "")

sl[0] = strings.ToUpper(sl[0])

name = strings.Join(sl, "")

structValue := reflect.ValueOf(obj).Elem() //结构体属性值

//fmt.Printf("structValue: %+v\n", structValue)

structFieldValue := structValue.FieldByName(name) //结构体单个属性值

//fmt.Printf("structFieldValue: %+v\n", structFieldValue)

if !structFieldValue.IsValid() {

return fmt.Errorf("No such field: %s in obj", name)

}

if !structFieldValue.CanSet() {

return fmt.Errorf("Cannot set %s field value", name)

}

structFieldType := structFieldValue.Type() //结构体的类型

val := reflect.ValueOf(value) //map值的反射值

if structFieldType != val.Type() {

return errors.New("type is err")

}

structFieldValue.Set(val)

return nil

}

在go社区有人解决了我的问题

回答

以上是 【go】【golang】想用反射做一个map数组转结构体数组的方法,代码如下,怎么把反射生成的结构体加进数组里? 的全部内容, 来源链接: www.h5w3.com/114910.html

回到顶部