func GetMulti(c context.Context, key []*Key, dst interface{}) error {
	v := reflect.ValueOf(dst)
	multiArgType, _ := checkMultiArg(v)
	if multiArgType == multiArgTypeInvalid {
		return errors.New("datastore: dst has invalid type")
	}
	if len(key) != v.Len() {
		return errors.New("datastore: key and dst slices have different length")
	}
	if len(key) == 0 {
		return nil
	}
	if err := multiValid(key); err != nil {
		return err
	}
	req := &pb.GetRequest{
		Key: multiKeyToProto(internal.FullyQualifiedAppID(c), key),
	}
	res := &pb.GetResponse{}
	if err := internal.Call(c, "datastore_v3", "Get", req, res); err != nil {
		return err
	}
	if len(key) != len(res.Entity) {
		return errors.New("datastore: internal error: server returned the wrong number of entities")
	}
	multiErr, any := make(appengine.MultiError, len(key)), false
	for i, e := range res.Entity {
		if e.Entity == nil {
			multiErr[i] = ErrNoSuchEntity
		} else {
			elem := v.Index(i)
			if multiArgType == multiArgTypePropertyLoadSaver || multiArgType == multiArgTypeStruct {
				elem = elem.Addr()
			}
			if multiArgType == multiArgTypeStructPtr && elem.IsNil() {
				elem.Set(reflect.New(elem.Type().Elem()))
			}
			multiErr[i] = loadEntity(elem.Interface(), e.Entity)
		}
		if multiErr[i] != nil {
			any = true
		}
	}
	if any {
		return multiErr
	}
	return nil
}
func GetMulti(c context.Context, key []*Key, dst interface{}) error {
	v := reflect.ValueOf(dst)
	multiArgType, _ := checkMultiArg(v)
	if multiArgType == multiArgTypeInvalid {
		return errors.New("datastore: dst has invalid type")
	}
	if len(key) != v.Len() {
		return errors.New("datastore: key and dst slices have different length")
	}
	if len(key) == 0 {
		return nil
	}
	if err := multiValid(key); err != nil {
		return err
	}
	req := &pb.GetRequest{
		Key: multiKeyToProto(internal.FullyQualifiedAppID(c), key),
	}
	res := &pb.GetResponse{}
	if err := internal.Call(c, "datastore_v3", "Get", req, res); err != nil {
		return err
	}
	if len(key) != len(res.Entity) {
		return errors.New("datastore: internal error: server returned the wrong number of entities")
	}
	multiErr, any := make(appengine.MultiError, len(key)), false
	for i, e := range res.Entity {
		if e.Entity == nil {
			multiErr[i] = ErrNoSuchEntity
		} else {
			elem := v.Index(i)
			if multiArgType == multiArgTypePropertyLoadSaver || multiArgType == multiArgTypeStruct {
				elem = elem.Addr()
			}
			if multiArgType == multiArgTypeStructPtr && elem.IsNil() {
				elem.Set(reflect.New(elem.Type().Elem()))
			}
			multiErr[i] = loadEntity(elem.Interface(), e.Entity)
		}
		if multiErr[i] != nil {
			any = true
		}
	}
	if any {
		return multiErr
	}
	return nil
}
func GetMulti ( c context . Context , key [ ] * Key , dst interface { } ) error { v := reflect . ValueOf ( dst ) multiArgType , _ := checkMultiArg ( v ) if multiArgType == multiArgTypeInvalid { return errors . New ( " " ) } if len ( key ) != v . Len ( ) { return errors . New ( " " ) } if len ( key ) == 0 { return nil } if err := multiValid ( key ) ; err != nil { return err } req := & pb . GetRequest { Key : multiKeyToProto ( internal . FullyQualifiedAppID ( c ) , key ) , } res := & pb . GetResponse { } if err := internal . Call ( c , " " , " " , req , res ) ; err != nil { return err } if len ( key ) != len ( res . Entity ) { return errors . New ( " " ) } multiErr , any := make ( appengine . MultiError , len ( key ) ) , false for i , e := range res . Entity { if e . Entity == nil { multiErr [ i ] = ErrNoSuchEntity } else { elem := v . Index ( i ) if multiArgType == multiArgTypePropertyLoadSaver || multiArgType == multiArgTypeStruct { elem = elem . Addr ( ) } if multiArgType == multiArgTypeStructPtr && elem . IsNil ( ) { elem . Set ( reflect . New ( elem . Type ( ) . Elem ( ) ) ) } multiErr [ i ] = loadEntity ( elem . Interface ( ) , e . Entity ) } if multiErr [ i ] != nil { any = true } } if any { return multiErr } return nil }
// GetMulti is a batch version of Get.
//
// dst must be a []S, []*S, []I or []P, for some struct type S, some interface
// type I, or some non-interface non-pointer type P such that P or *P
// implements PropertyLoadSaver. If an []I, each element must be a valid dst
// for Get: it must be a struct pointer or implement PropertyLoadSaver.
//
// As a special case, PropertyList is an invalid type for dst, even though a
// PropertyList is a slice of structs. It is treated as invalid to avoid being
// mistakenly passed when []PropertyList was intended.
GetMulti is a batch version of Get . dst must be a [] S [] * S [] I or [] P for some struct type S some interface type I or some non - interface non - pointer type P such that P or * P implements PropertyLoadSaver . If an [] I each element must be a valid dst for Get : it must be a struct pointer or implement PropertyLoadSaver . As a special case PropertyList is an invalid type for dst even though a PropertyList is a slice of structs . It is treated as invalid to avoid being mistakenly passed when [] PropertyList was intended .