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-09-06 17:47:01

golang map to struct的例子的相关文章

golang语言strconv包使用例子

golang strconv包提供了字符串和基本数据类型之间的转换操作. 1.默认提供了1个常量IntSize和两个变量ErrRange和ErrSyntax. package main   import (  "strconv"  "fmt" )   func main()  {  //IntSize是int或uint类型的字位数.  fmt.Println(strconv.IntSize)  //ErrRange表示超出目标类型表示范围.[var ErrRange

Go语言struct类型详解_Golang

struct Go语言中,也和C或者其他语言一样,我们可以声明新的类型,作为其它类型的属性或字段的容器.例如,我们可以创建一个自定义类型person代表一个人的实体.这个实体拥有属性:姓名和年龄.这样的类型我们称之struct.如下代码所示: 复制代码 代码如下: type person struct {     name string     age int } 看到了吗?声明一个struct如此简单,上面的类型包含有两个字段. 1.一个string类型的字段name,用来保存用户名称这个属性

js实现的map方法

 本文为大家介绍下使用js实现的map方法,具体示例如下,喜欢的朋友可以了解下  代码如下: /**  *  * 描述:js实现的map方法  * @returns {Map}  */  function Map(){  var struct = function(key, value) {  this.key = key;  this.value = value;  };  // 添加map键值对  var put = function(key, value){  for (var i = 0

golang精华资源

我从几个月前用go学go算是入道了,看了大量的书,做了大量的例子,收藏了不少干货,在这里分享给大家,欢迎关注gostock微信公众号,持续更新:) 1.Learning Go <学习Go语言> http://www.miek.nl/projects/learninggo/ 中文版http://mikespook.com/learning-go/ 2.Go by Example Go is an open source programming language designed for buil

js实现的map方法示例代码_javascript技巧

复制代码 代码如下: /** * * 描述:js实现的map方法 * @returns {Map} */ function Map(){ var struct = function(key, value) { this.key = key; this.value = value; }; // 添加map键值对 var put = function(key, value){ for (var i = 0; i < this.arr.length; i++) { if ( this.arr[i].k

MySQL · myrocks · myrocks之事务处理

前言 mysql目前支持的事务引擎有innodb,tokudb. rocksdb加入mysql阵营后,mysql支持的事务引擎增长至3个. myrocks目前支持的事务隔离级别有read-committed和repeatable-read. 同innodb一样,myrocks也支持MVCC机制. 可以说,myrocks提供了很好的事务支持,能够满足的一般业务的事务需求. sequence number 谈到rocksdb事务,就必须提及rocksdb中的sequence number机制.roc

myrocks之事务处理

title: MySQL · myrocks · myrocks之事务处理 author: 张远 前言 mysql目前支持的事务引擎有innodb,tokudb. rocksdb加入mysql阵营后,mysql支持的事务引擎增长至3个.myrocks目前支持的事务隔离级别有read-committed和repeatable-read. 同innodb一样,myrocks也支持MVCC机制. 可以说,myrocks提供了很好的事务支持,能够满足的一般业务的事务需求. sequence number

Go语言展现快速排序算法全过程的思路及代码示例_Golang

快速排序算法快速排序是一个递归的思想,首先选择一个数作为基数,把数组中小于它的数放在它的左边,把大于它的数放在它的右边,然后对左右两边的数递归进行排序. 算法的关键部分是实现数组的划分,即怎么把数组的元素划分成两部分,使得左边的数比基数小,右边的数比基数大.划分有许多不同的实现方法,这里主要使用单向扫描的方法,后面再稍微介绍双向扫描的方法. 选择最右边的数字作为基数.使用一个变量j记录当前左边数字(比基数小的数)的最右的下标值.然后使用变量i从左到右遍历数组,如果a[i]比基数小,说明a[i]属

2017值得一瞥的JavaScript相关技术趋势

2017值得一瞥的JavaScript相关技术趋势从属于笔者的Web 前端入门与工程实践,推荐阅读2016-我的前端之路:工具化与工程化获得更多关于2016年前端总结.本文主要内容翻译自,笔者对于每个条目进行了些许完善. 本文中提及的这些趋势可能离大部分开发者还很远,或者说离真正的大规模工程化应用还很远,不过不妨碍我们提前两三年了解下.本文仅代表原作者个人看法,不喜留言轻喷,译者也很好奇大家对这个列表的看法. 跨年前两天,Dan Abramov在Twitter上提了一个问题: JS社区毫不犹豫的