| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 | package svcimport (	"fmt"	"reflect"		"golib/features/mo")func ValueType(v any) reflect.Type {	return reflect.ValueOf(v).Type()}// toMaps// 由于 mo.M 并非 map[string]interface{} 的别名, 而是重新定义的类型. 因此在实际开发环境中可能会出现混用的情况. 这时将无法直接使用断言// 来确定类型: toMaps 即一劳永逸的解决各种底层为 map 类型的类型之间断言的问题// 参数 f 提供一个操作函数, toMaps 会在循环时确定当前元素为 map 类型后将当前 map 传入 f 并调用: f(m)// 函数 f 可以修改 m// 最后 m 会保存至 docs 内func (s *Service) toMaps(docs mo.A, f func(m mo.M) error) error {	rv := reflect.ValueOf(docs)	for i := 0; i < rv.Len(); i++ {		row := mo.M{}		rvr := reflect.ValueOf(rv.Index(i).Interface())		if rvr.Kind() != reflect.Map {			s.Logs.Println("svc.toMaps: the %d element must be map: %s", i, docs)			return fmt.Errorf("the %d element must be map: %s", i, docs)		}				rvm := rvr.MapRange()		for rvm.Next() {			if rvm.Key().Kind() != reflect.String {				s.Logs.Println("svc.toMaps: the %d element map key must be string: %s", i, docs)				return fmt.Errorf("the %d element map key must be string: %s", i, docs)			}			rmk := rvm.Key().String()			rmv := rvm.Value().Interface()			// 处理 _id 类型			if rmk == mo.ID.Key() {				if oid, ok := rmv.(mo.ObjectID); !(ok && !oid.IsZero()) {					return fmt.Errorf("the %d element map _id must be mo.ObjectID: %s", i, docs)				}			}			row[rmk] = rmv		}				if f != nil {			if err := f(row); err != nil {				return err			}		}		docs[i] = row	}	return nil}
 |