golang map to struct

map映射到结构体,这里只支持简单的数据类型,复杂的需要在拓展

package main

import (
	"errors"
	"fmt"
	"reflect"
	"strconv"
	"time"
)

type User struct {
	Name string
	Age  int8
	Date time.Time
}

func main() {

	data := make(map[string]interface{})
	data["Name"] = "张三"
	data["Age"] = 26
	data["Date"] = "2015-09-29 00:00:00"

	result := &User{}
	err := FillStruct(data, result)
	fmt.Println(err, fmt.Sprintf("%+v", *result))
}

//用map填充结构
func FillStruct(data map[string]interface{}, obj interface{}) error {
	for k, v := range data {
		err := SetField(obj, k, v)
		if err != nil {
			return err
		}
	}
	return nil
}

//用map的值替换结构的值
func SetField(obj interface{}, name string, value interface{}) error {
	structValue := reflect.ValueOf(obj).Elem()        //结构体属性值
	structFieldValue := structValue.FieldByName(name) //结构体单个属性值

	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值的反射值

	var err error
	if structFieldType != val.Type() {
		val, err = TypeConversion(fmt.Sprintf("%v", value), structFieldValue.Type().Name()) //类型转换
		if err != nil {
			return err
		}
	}

	structFieldValue.Set(val)
	return nil
}

//类型转换
func TypeConversion(value string, ntype string) (reflect.Value, error) {
	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)
}
时间: 2024-12-16 04:32:05

golang map to struct的相关文章

golang json处理struct未导出成员

我们用golang的json来marshal一个结构体的时候,结构体的未导出的成员将无法被json访问,也就是不会出现json编码的结果里(也就是小写的成员没法导出) 这个是由于技术的上问题引起的:golang的结构体里的成员的名字如果以小写字母开头,那么其他的包是无法访问的,也就是json无法访问我们的结构体里小写字母开头的成员 这个可以有两种方法解决 1. struct的成员用大写开头,然后加tag 2. 实现json.Marshaler接口 第一种方法比较常见这儿就不详细展开了 第二种方法

golang map性能测试

golang map是golang的方便操作的key-value package main import ( "fmt" "math/rand" "time" _"strconv" ) var x = make(map[int]int, 100000001) //var x = make(map[string]string, 100000001) func main() { ttime := time.Now().UnixNa

Go_14:GoLang中 json、map、struct 之间的相互转化

1. golang 中 json 转 struct <1. 使用 json.Unmarshal 时,结构体的每一项必须是导出项(import field).也就是说结构体的 key 对应的首字母必须为大写.请看下面的例子: package commontest import ( "testing" "encoding/json" ) type Person struct { name string age int } func TestStruct2Json(

hive--[ array、map、struct]使用

h2 { color: #fff; background-color: #7CCD7C; padding: 3px; margin: 10px 0px } h3 { color: #fff; background-color: #008eb7; padding: 3px; margin: 10px 0px } 复合数据类型 Structs: structs内部的数据可以通过DOT(.)来存取,例如,表中一列c的类型为STRUCT{a INT; b INT},我们可以通过c.a来访问域a Maps

hive array、map、struct使用

hive提供了复合数据类型:Structs: structs内部的数据可以通过DOT(.)来存取,例如,表中一列c的类型为STRUCT{a INT; b INT},我们可以通过c.a来访问域aMaps(K-V对):访问指定域可以通过["指定域名称"]进行,例如,一个Map M包含了一个group->gid的kv对,gid的值可以通过M['group']来获取Arrays:array中的数据为相同类型,例如,假如array A中元素['a','b','c'],则A[1]的值为'b'

golang 格式化打印struct

//type:interface value:sturct func PrintStruct(t reflect.Type, v reflect.Value, pc int) { fmt.Println("") for i := 0; i < t.NumField(); i++ { fmt.Print(strings.Repeat(" ", pc), t.Field(i).Name, ":") value := v.Field(i) Pri

golang获取packed struct的大小

网络协议里面,很可能遇到自定义的封包,对应到c里面的是 typedef struct _PackageHeader { int headerLen; int timeStamp; short cmd }; 为了保证单字节对齐,可以加上编译选项 #pragma pack(1) 可惜的是,golang里面,没有这样的编译选项,猥琐的可参考的山寨代码如下 package main import ( "encoding/binary" "fmt" ) type TestSt

std::map, struct pointer 为key

template < class Key, // map::key_type class T, // map::mapped_type class Compare = less<Key>, // map::key_compare class Alloc = allocator<pair<const Key,T> > // map::allocator_type > class map; struct Cell{ int x; int y; Cell(int

golang map

Our friend Monk has been made teacher for the day today by his school professors . He is going to teach informatics to his colleagues as that is his favorite subject . Before entering the class, Monk realized that he does not remember the names of al