【问题标题】:How to sub slice an interface{} that is a slice?如何对作为切片的接口{}进行子切片?
【发布时间】:2014-04-04 18:22:27
【问题描述】:

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.

【问题讨论】:

    标签: google-app-engine go


    【解决方案1】:

    由于您是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)
    }
    

    【讨论】:

    • 感谢您的帮助。我有一个follow up question,以防你能回答。
    • 我会避免同时使用i 作为输入参数和迭代变量,这很令人困惑。反正答案很好
    猜你喜欢
    • 2017-08-29
    • 2020-04-17
    • 2020-02-03
    • 1970-01-01
    • 2019-01-13
    • 1970-01-01
    • 2012-02-25
    • 1970-01-01
    • 2012-10-11
    相关资源
    最近更新 更多