[英]How to sub slice an interface{} that is a slice?
The datastore.GetMulti(c appengine.Context, key []*Key, dst interface{})
API allows me to get 1000 entities at most. datastore.GetMulti(c appengine.Context, key []*Key, dst interface{})
API允许我最多获得1000个实体。 I want to get more. 我想得到更多。
An obvious way to solve this generically is to create a wrapper function mypkg.GetMulti()
which sub slices ( key[0:1000], key[1000:2000]...
) the original arguments and calls datastore.GetMulti()
several times with them. 一般来说解决这个问题的一个明显方法是创建一个包装函数mypkg.GetMulti()
,其子切片( key[0:1000], key[1000:2000]...
)原始参数并调用datastore.GetMulti()
几个和他们在一起。
It's pretty clear how to sub slice key []*Key
, but how do I sub slice dst interface{}
which could be: 很清楚如何分切片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.
Since you are the caller of datastore.GetMulti
which takes an interface{}
argument, you can provide any concrete value as that argument; 由于您是采用interface{}
参数的datastore.GetMulti
的调用者,因此您可以提供任何具体值作为该参数; it doesn't need to be converted to the empty-interface type beforehand. 它不需要事先转换为空接口类型。 In other words, anything and everything implements the empty interface, so just pass that thing. 换句话说,任何东西都可以实现空接口,所以只需传递那个东西。
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
}
}
In case mypkg.GetMulti
should be a generic function, taking an interface{}
value as well, then you'll have to use reflection as in the following example where instead of fmt.Println
with the length of the subslice you'd call datastore.GetMulti
with each subslice: 如果mypkg.GetMulti
应该是一个泛型函数,同样取一个interface{}
值,那么你将不得不使用反射,如下例所示 ,而不是fmt.Println
,而你的fmt.Println
长度你称之为datastore.GetMulti
与每个子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)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.