如何对一个界面切片进行分片? [英] How to sub slice an interface{} that is a slice?

查看:151
本文介绍了如何对一个界面切片进行分片?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆