2014-04-04 23 views
0

datastore.GetMulti(c appengine.Context, key []*Key, dst interface{}) API允许我最多获得1000个实体。我想获得更多。如何划分一个界面{},这是一个切片?

一个明显的方法来解决这个一般是创建一个包装函数mypkg.GetMulti()哪些子片(key[0:1000], key[1000:2000]...)原始参数和调用datastore.GetMulti()几次与他们。

这是很清楚如何分片key []*Key,但我怎么分片dst interface{}这可能是:

// 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. 

回答

2

既然你是datastore.GetMulti这需要一个interface{}参数调用者,可以提供任何具体的值作为这个论点;它不需要事先转换为空接口类型。换句话说,任何东西和所有东西都实现了空的接口,所以只需传递那个东西。

func GetMulti() { 
    mySlice := make([]Whatever, 3000, 3000) 
    for i := 0; i < 3; i++ { 
     subSlice := mySlice[i * 1000 : (i + 1) * 1000] 
     datastore.GetMulti(c,k, subSlice) // 'c' and 'k' assumed to be defined 
    } 
} 

如果mypkg.GetMulti应该是一个通用的功能,服用interface{}价值为好,那么你就必须在以下example使用反射的地方,而不是fmt.Println与你所说的子切片的长度datastore.GetMulti每个子切片:

package main 

import "fmt" 
import "reflect" 

func GetMulti(i interface{}) { 
    v := reflect.ValueOf(i) 
    if v.Kind() != reflect.Slice { 
     panic("argument not a slice") 
    } 
    l := v.Len() 
    p := (l/1000) 
    for i := 0; i < p; i++ { 
     fmt.Println(v.Slice(i*1000, (i+1)*1000).Len()) 
    } 
    fmt.Println(v.Slice(p*1000, l).Len()) 

} 

func main() { 
    s := make([]int, 3560, 3560) 
    GetMulti(s) 
} 
+0

感谢您的帮助。如果您能够回答,我有[后续问题](http://stackoverflow.com/questions/22885336/passing-reflect-value-to-datastore-getmulti-in-google-app-engine)。 – Dan