http://stackoverflow.com/questions/26744873/converting-map-to-struct

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)
if structFieldType != val.Type() {
return errors.New("Provided value type didn't match obj field type")
} structFieldValue.Set(val)
return nil
} type MyStruct struct {
Name string
Age int64
} func (s *MyStruct) FillStruct(m map[string]interface{}) error {
for k, v := range m {
err := SetField(s, k, v)
if err != nil {
return err
}
}
return nil
} func main() {
myData := make(map[string]interface{})
myData["Name"] = "Tony"
myData["Age"] = int64() result := &MyStruct{}
err := result.FillStruct(myData)
if err != nil {
fmt.Println(err)
}
fmt.Println(result)
}

从mysql的结果到某个struct

type operConf struct {
Id uint32 `sql:"oper_id"`
Name string `sql:"oper_name"`
MsgRetyTimes uint32 `sql:"msg_retry_times"`
MsgRetyInterval uint32 `sql:"msg_retry_interval"`
HeartBeartInterval uint32 `sql:"heartbeat_interval"`
OfflineDetectTime uint32 `sql:"offline_detect_time"`
} func GetOperConf() ([]operConf, error) {
host := GetConf().MySql.Host
port := GetConf().MySql.Port
user := GetConf().MySql.User
password := GetConf().MySql.Pwd
dbName := GetConf().MySql.Db
table := GetConf().MySql.Table sql := new(mysql)
defer sql.Close()
if err := sql.Connect(host, port, user, password, dbName, table); err != nil {
logger.DEBUG(LOG_NAME, "slq.Connect err:%s", err.Error())
return nil, err
} sqlStr := "SELECT oper_id, oper_name, msg_retry_times, msg_retry_interval, heartbeat_interval, offline_detect_time"
sqlStr += " From " + table result, err := sql.Query(sqlStr)
if err != nil {
return nil, err
}
confArr := make([]operConf, len(result))
for i, v := range result {
oc := new(operConf)
DataToStruct(v, oc)
logger.DEBUG(LOG_NAME, "oc:%+v", oc)
confArr[i] = *oc }
return nil, nil } type mysql struct {
m_db *sql.DB
} func (this *mysql) Connect(host string, port int, user, password, dbName, table string) error {
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8",
user, password, host, port, dbName) var err error
this.m_db, err = sql.Open("mysql", dsn)
if err != nil {
fmt.Println("error: %s\n", err.Error())
return err
}
err = this.m_db.Ping()
if err != nil {
this.m_db.Close()
}
return err
} func (this *mysql) Close() {
this.m_db.Close()
} func (this *mysql) Query(sql string) (map[int]map[string]string, error) {
if this.m_db == nil {
return nil, errors.New("mysql not connect")
}
var query = strings.TrimSpace(sql)
s, err := regexp.MatchString(`(?i)^select`, query) //(?i) igonre upper/lower case if err != nil {
return nil, err
}
if s == false {
return nil, errors.New("not select sql")
} rows, _ := this.m_db.Query(sql)
c, err := this.GetQueryResult(rows)
return c, err
} func (this *mysql) GetQueryResult(rows *sql.Rows) (map[int]map[string]string, error) {
var result = make(map[int]map[string]string)
columns, _ := rows.Columns()
values := make([]sql.RawBytes, len(columns))
scanArgs := make([]interface{}, len(values))
for i := range values {
scanArgs[i] = &values[i]
} var n =
for rows.Next() {
result[n] = make(map[string]string)
err := rows.Scan(scanArgs...) if err != nil {
return nil, err
} for i, v := range values {
result[n][columns[i]] = string(v)
}
n++
} logger.DEBUG(LOG_NAME, "Query Result:%+v", result)
return result, nil
} func DataToStruct(data map[string]string, out interface{}) {
ss := reflect.ValueOf(out).Elem()
for i := ; i < ss.NumField(); i++ {
val := data[ss.Type().Field(i).Tag.Get("sql")]
name := ss.Type().Field(i).Name
logger.DEBUG(LOG_NAME, "tag:%s, tag value:%s, filed name:%s", ss.Type().Field(i).Tag.Get("sql"), val, name)
switch ss.Field(i).Kind() {
case reflect.String:
ss.FieldByName(name).SetString(val)
case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64:
i, err := strconv.Atoi(val)
// fmt.Println("i:", i, name)
if err != nil {
logger.ERROR(LOG_NAME, "can't not atoi:%v", val)
continue
}
ss.FieldByName(name).SetInt(int64(i))
case reflect.Uint16, reflect.Uint32, reflect.Uint64:
i, err := strconv.Atoi(val)
// fmt.Println("i:", i, name)
if err != nil {
logger.ERROR(LOG_NAME, "can't not atoi:%v", val)
continue
}
ss.FieldByName(name).SetUint(uint64(i))
case reflect.Float32, reflect.Float64:
f, err := strconv.ParseFloat(val, )
if err != nil {
logger.ERROR(LOG_NAME, "can't not ParseFloat:%v", val)
continue
}
ss.FieldByName(name).SetFloat(f)
default:
logger.ERROR(LOG_NAME, "unknown type:%+v", ss.Field(i).Kind())
}
}
return
}

golang map to struct的更多相关文章

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

    1. golang 中 json 转 struct <1. 使用 json.Unmarshal 时,结构体的每一项必须是导出项(import field).也就是说结构体的 key 对应的首字母 ...

  2. GoLang中 json、map、struct 之间的相互转化

    1. golang 中 json 转 struct <1. 使用 json.Unmarshal 时,结构体的每一项必须是导出项(import field).也就是说结构体的 key 对应的首字母 ...

  3. golang 中 map 转 struct

    golang 中 map 转 struct package main import ( "fmt" "github.com/goinggo/mapstructure&qu ...

  4. golang struct 转map 及 map[string]*Struct 初始化和遍历

    package main import ( "encoding/json" "errors" "fmt" "reflect&quo ...

  5. golang map输出排序

    由于GoLang Map 内部存储是无序的,当需要按顺序获得map存储的key -value值时,应该对遍历出来的结果进行重新排序: 在go 1.8版本后,提供的slice sort 功能使排序更简单 ...

  6. Golang Map实现(一)

    本文学习 Golang 的 Map 数据结构,以及map buckets 的数据组织结构. hash 表是什么 从大学的课本里面,我们学到:hash 表其实就是将key 通过hash算法映射到数组的某 ...

  7. Golang Map实现(四) map 的赋值和扩容

    title: Golang Map 实现 (四) date: 2020-04-28 18:20:30 tags: golang map 操作,是map 实现中较复杂的逻辑.因为当赋值时,为了减少has ...

  8. 【GoLang】GoLang map 非线程安全 & 并发度写优化

    Catena (时序存储引擎)中有一个函数的实现备受争议,它从 map 中根据指定的 name 获取一个 metricSource.每一次插入操作都会至少调用一次这个函数,现实场景中该函数调用更是频繁 ...

  9. Golang面向对象编程-struct(结构体)

    Golang面向对象编程-struct(结构体) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是面向对象编程 面向对象编程(Object Oriented Program ...

随机推荐

  1. Educational Codeforces Round 37 (Rated for Div. 2)

    我的代码应该不会被hack,立个flag A. Water The Garden time limit per test 1 second memory limit per test 256 mega ...

  2. Educational Codeforces Round 20 D. Magazine Ad

    The main city magazine offers its readers an opportunity to publish their ads. The format of the ad ...

  3. 读懂diff(转载)

    作者: 阮一峰 日期: 2012年8月29日 diff是Unix系统的一个很重要的工具程序. 它用来比较两个文本文件的差异,是代码版本管理的基石之一.你在命令行下,输入: $ diff <变动前 ...

  4. chef and churu 分块 好题

    题目大意 有一个长度为n的数组A 有n个函数,第i个函数 \[f(l[i],r[i])=\sum_{k=l[i]}^{r[i]}A_k\] 有两种操作: 1)修改A[i] 2)询问第x-y个函数值的和 ...

  5. yii框架缓存知识总结(转载)

    缓存是用于提升网站性能的一种即简单又有效的途径.稍微有点规模的网站都会通过存储相对静态的数据至缓存以备所需,这样我们可以省去从数据库查询然后生成这些数据的时间,通过减轻数据库的压力从而提升网站的性能. ...

  6. est6 -- Object.is()、Object.assign()、Object.defineProperty()、Symbol、Proxy

    Object.is()用来比较两个值是否严格相等.它与严格比较运算符(===)的行为基本一致,不同之处只有两个:一是+0不等于-0,二是NaN等于自身. + === - //true NaN === ...

  7. .Net Core中的配置文件源码解析

    一.配置简述 之前在.Net Framework平台开发时,一般配置文件都是xml格式的Web.config,而需要配置其他格式的文件就需要自己去读取内容,加载配置了..而Net Core支持从命令行 ...

  8. 通过房价预测入门Kaggle

    今天看了个新闻,说是中国社会科学院城市发展与环境研究所及社会科学文献出版社共同发布<房地产蓝皮书:中国房地产发展报告No.16(2019)>指出房价上涨7.6%,看得我都坐不住了,这房价上 ...

  9. python安装numpy和matplotlib

    1.从该链接下载对应的whl文件 2.按照下面的方式从whl文件安装即可 windows7 python2.7 1.用管理员方式打开cmd 2.首先通过pip命令安装wheel 如果提示’pip’不是 ...

  10. codevs——1814 最长链

    1814 最长链  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description 现给出一棵N个结点二叉树,问这棵二叉 ...