drpzr64329 2014-04-04 09:59
浏览 105
已采纳

如何对作为切片的接口{}进行切片?

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.
  • 写回答

1条回答 默认 最新

  • dongtiandexue123456 2014-04-04 10:08
    关注

    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)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 angular开发过程中,想要读取模型文件,即图1的335行,会报404错误(如图2)。但我的springboot里配置了静态资源文件,如图3。且在该地址下我有模型文件如图4,请问该问题该如何解决呢?
  • ¥15 itunes恢复数据最后一步发生错误
  • ¥15 关于#windows#的问题:2024年5月15日的win11更新后资源管理器没有地址栏了顶部的地址栏和文件搜索都消失了
  • ¥100 H5网页如何调用微信扫一扫功能?
  • ¥15 讲解电路图,付费求解
  • ¥15 有偿请教计算电磁学的问题涉及到空间中时域UTD和FDTD算法结合的
  • ¥15 vite打包后,页面出现h.createElement is not a function,但本地运行正常
  • ¥15 Java,消息推送配置
  • ¥15 Java计划序号重编制功能,此功能会对所有序号重新排序,排序后不改变前后置关系。
  • ¥15 关于哈夫曼树应用得到一些问题