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(23)      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 = 0     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 := 0; 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, 64)             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 }