map->bsonM
//map转bsonm
func ToBsonM(r interface{}) bson.M {
result := make(bson.M)
v := reflect.ValueOf(r)
t := reflect.TypeOf(r)
for i := 0; i < v.NumField(); i++ {
filed := v.Field(i)
tag := t.Field(i).Tag
key := tag.Get("json")
if key == "" || key == "-" || key == "_id" {
continue
}
keys := strings.Split(key, ",")
if len(keys) > 0 {
key = keys[0]
}
// TODO: 处理字段嵌套问题
switch filed.Kind() {
case reflect.Int, reflect.Int64:
v := filed.Int()
if v != 0 {
result[key] = v
}
case reflect.String:
v := filed.String()
if v != "" {
result[key] = v
}
case reflect.Bool:
result[key] = filed.Bool()
case reflect.Ptr:
case reflect.Float64:
v := filed.Float()
if v != 0 {
result[key] = v
}
case reflect.Float32:
v := filed.Float()
if v != 0 {
result[key] = v
}
default:
}
}
return result
}
struct->bsonM
// ToMap 结构体转为Map[string]interface{}
func StructToMap(in interface{}, tagName string) (map[string]interface{}, error) {
out := make(map[string]interface{})
v := reflect.ValueOf(in)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
if v.Kind() != reflect.Struct { // 非结构体返回错误提示
return nil, fmt.Errorf("ToMap only accepts struct or struct pointer; got %T", v)
}
t := v.Type()
// 遍历结构体字段
// 指定tagName值为map中key;字段值为map中value
for i := 0; i < v.NumField(); i++ {
fi := t.Field(i)
if tagValue := fi.Tag.Get(tagName); tagValue != "" {
out[tagValue] = v.Field(i).Interface()
}
}
return out, nil
}