| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 | package svcimport (	"errors"	"fmt"	"strings"	"golib/features/mo"	"golib/infra/ii")// 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 {	for i := 0; i < len(docs); i++ {		if row, ok := docs[i].(mo.M); ok {			if err := f(row); err != nil {				s.Log.Error("svc.toMaps: the %d element handled: %s", i, err)				return err			}		} else {			b, err := mo.MarshalExtJSON(docs[i], true, true)			if err != nil {				s.Log.Error("svc.toMaps: the %d element MarshalExtJSON: %s", i, err)				return err			}			var m mo.M			if err = mo.UnmarshalExtJSON(b, true, &m); err != nil {				s.Log.Error("svc.toMaps: the %d element UnmarshalExtJSON: %s", i, err)				return err			}			if err = f(m); err != nil {				s.Log.Error("svc.toMaps: the %d element handled: %s", i, err)				return err			}			docs[i] = m		}	}	return nil}func splitPATH(path, prefix string) (string, ii.Name, error) {	// "","item","insertOne","test.user"	pathList := strings.Split(path, "/")	if len(pathList) != 4 {		return "", "", fmt.Errorf("err path: %s", path)	}	if pathList[1] != prefix {		return "", "", errors.New("the first element of PATH must be: item")	}	return pathList[2], ii.Name(pathList[3]), nil}
 |