这个函数在哪里返回非错误?

时间:2015-10-09 21:01:49

标签: go google-cloud-datastore

我正在构建数据存储区GetAll函数的包装器,我很难找到此函数返回非错误的位置。在我看来,除非有任何其他错误(即当它在Done上中断时),它返回errFieldMismatch,我认为这是不正确的。

func (q *Query) GetAll(c context.Context, dst interface{}) ([]*Key, error) {
    var (
        dv               reflect.Value
        mat              multiArgType
        elemType         reflect.Type
        errFieldMismatch error
    )
    if !q.keysOnly {
        dv = reflect.ValueOf(dst)
        if dv.Kind() != reflect.Ptr || dv.IsNil() {
            return nil, ErrInvalidEntityType
        }
        dv = dv.Elem()
        mat, elemType = checkMultiArg(dv)
        if mat == multiArgTypeInvalid || mat == multiArgTypeInterface {
            return nil, ErrInvalidEntityType
        }
    }

    var keys []*Key
    for t := q.Run(c); ; {
        k, e, err := t.next()
        if err == Done {
            break
        }
        if err != nil {
            return keys, err
        }
        if !q.keysOnly {
            ev := reflect.New(elemType)
            if elemType.Kind() == reflect.Map {
                // This is a special case. The zero values of a map type are
                // not immediately useful; they have to be make'd.
                //
                // Funcs and channels are similar, in that a zero value is not useful,
                // but even a freshly make'd channel isn't useful: there's no fixed
                // channel buffer size that is always going to be large enough, and
                // there's no goroutine to drain the other end. Theoretically, these
                // types could be supported, for example by sniffing for a constructor
                // method or requiring prior registration, but for now it's not a
                // frequent enough concern to be worth it. Programmers can work around
                // it by explicitly using Iterator.Next instead of the Query.GetAll
                // convenience method.
                x := reflect.MakeMap(elemType)
                ev.Elem().Set(x)
            }
            if err = loadEntity(ev.Interface(), e); err != nil {
                if _, ok := err.(*ErrFieldMismatch); ok {
                    // We continue loading entities even in the face of field mismatch errors.
                    // If we encounter any other error, that other error is returned. Otherwise,
                    // an ErrFieldMismatch is returned.
                    errFieldMismatch = err
                } else {
                    return keys, err
                }
            }
            if mat != multiArgTypeStructPtr {
                ev = ev.Elem()
            }
            dv.Set(reflect.Append(dv, ev))
        }
        keys = append(keys, k)
    }
    return keys, errFieldMismatch
}

1 个答案:

答案 0 :(得分:1)

默认是返回errFieldMismatch,它是声明的,但未在函数顶部初始化。

如果在迭代期间的任何时候都没有ErrFieldMismatcherrFieldMismatch最后仍然是nil,因此GetAll将返回{ {1}}错误。