我尝试使用此功能获取多个值(来自go-couchbase)。
func (b *Bucket) Gets(k string, rv interface{}, caso *uint64) error {
data, _, cas, err := b.GetsRaw(k)
if err != nil {
return err
}
if caso != nil {
*caso = cas
}
return json.Unmarshal(data, rv)
}
问题是我不知道如何创建一片rv,因为我不知道它的类型在我的函数中,我不知道它会有多大,所以我可以&# 39;真的通过索引访问rv
切片,对吗?
我希望尽可能通用,因此每个rv
结构创建一个函数并不是最佳的,而GetBulk函数只返回[]byte
。
甚至可以做我想做的事情吗?
答案 0 :(得分:4)
您可以使用reflect
包检查类型信息。如果我们有一个具有参数rv interface{}
的函数,我们期望传递一个切片的指针,我们可以创建一个引用该切片的reflect.Value
:
slice := reflect.ValueOf(rv).Elem()
我们可以按如下方式重新初始化切片:
slice.Set(reflect.MakeSlice(slice.Type(), length, capacity))
我们可以使用以下方法确定此切片的元素类型:
elemType := slice.Type().Elem()
然后创建另一个reflect.Value
,表示指向新分配的该类型实例的指针:
v := reflect.New(elemType)
现在v.Interface()
适合传递给json.Unmarshal
这样的函数。填充后,可以将其附加到切片:
slice.Set(reflect.Append(slice, v.Elem()))
有关将一片JSON文档解码为任意切片类型的完整示例,请参阅http://play.golang.org/p/G-SHQO2MAT
答案 1 :(得分:2)
考虑到go-couchbase#Bucket.Gets
需要一个界面,您需要将对象放入[]界面,如wiki页面中所述" InterfaceSlice"
var dataSlice []int = foo()
var interfaceSlice []interface{} = make([]interface{}, len(dataSlice))
for i, d := range dataSlice {
interfaceSlice[i] = d
}
这意味着你已经有了#34;"并且知道它的大小。
或者,既然你想围绕Gets
函数"建立一个函数,你可以使用相同的签名,并使用简单的interface{}
而不是{{1} }。