如何对一个界面切片进行分片? [英] How to sub slice an interface{} that is a slice?
问题描述
datastore.GetMulti(c appengine.Context,key [] * Key,dst interface {})
API允许我最多获得1000个实体。我想得到更多。
一个明显的解决方法是创建一个包装函数 mypkg.GetMulti()
哪些子片(键[0:1000],键[1000:2000] ...
)原始参数并调用 datastore.GetMulti ()
>几次与他们。
这很清楚如何分片键[] *键
,但我该如何分片 dst接口{}
可能是:
// dst必须是一个[] S,[] * S,[] I或[] P,对于某些结构类型S,某些接口
//类型I,接口非指针类型P,使得P或* P
//实现PropertyLoadSaver。如果[] I,每个元素必须是有效的dst
//对于Get:它必须是一个结构指针或实现PropertyLoadSaver。
//
//作为一种特殊情况,对于dst,PropertyList是无效的类型,即使
// PropertyList是一个结构片。它被视为无效,以避免当[] PropertyList被打算时被
//错误地传递。
既然你是 datastore.GetMulti
,它需要一个 interface {}
参数,您可以提供任何具体的值作为该参数;它不需要事先转换为空接口类型。换句话说,任何东西和所有东西都实现了空的接口,所以只需传递那个东西。
func GetMulti(){
mySlice:= make([]随便,3000,3000)
for i:= 0;我< 3; i ++ {
subSlice:= mySlice [i * 1000:(i + 1)* 1000]
datastore.GetMulti(c,k,subSlice)//'c'和'k'假定被定义
如果 mypkg.GetMulti
应该是一个通用函数,并且也需要 interface {}
值,那么您必须像下面的示例其中代替 fmt.Println
,长度为您可以为每个子切片调用 datastore.GetMulti
子切片:
package main
$ b $ importfmt
importreflect
func GetMulti(i interface {}){
v:= reflect.ValueOf(i )
如果v.Kind()!= reflect.Slice {
panic(argument not a slice)
}
l:= v.Len()
p :=(l / 1000)
for i:= 0;我<磷; 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($)
}
The datastore.GetMulti(c appengine.Context, key []*Key, dst interface{})
API allows me to get 1000 entities at most. 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.
It's pretty clear how to sub slice key []*Key
, but how do I sub slice dst interface{}
which could be:
// 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; 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:
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)
}
这篇关于如何对一个界面切片进行分片?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!