使用反射在Go中设置切片索引

20

我正在使用Go语言,处理一个slice的reflect.Value表示。以下是我的代码:

slice := reflect.MakeSlice(typ, len, cap)

如果我想从slice中获取第i个值,很简单:

v := slice.Index(i) // returns a reflect.Value

然而,我似乎找不到一种方法来设置第 i 个值。例如,如果我有一个映射 m,那么 reflect.Value 有很多设置器方法:

m.SetMapIndex(key, value) // key and value have type reflect.Value

但是似乎对于切片来说没有相应的功能。我的一个想法是,也许从 slice.Index(i) 返回的值实际上是某种指针,因此调用 v := slice.Index(i); v.Set(newV) 可能会起作用?我不确定。有什么想法吗?

2个回答

27

明白了!原来是我提前发布了这篇文章——我猜测 slice.Index(0) 返回的是一个指针,这个猜测是正确的。具体来说:

one := reflect.ValueOf(int(1))

slice := reflect.MakeSlice(reflect.TypeOf([]int{}), 1, 1)
v := slice.Index(0)
fmt.Println(v.Interface())

v.Set(one)
fmt.Println(v.Interface())

v = slice.Index(0)
fmt.Println(v.Interface())

输出:

0
1
1

(这里是可在Go Playground上运行的代码


1
这可能有所帮助:

n := val.Len()
if n >= val.Cap() {
    ncap := 2 * n
    if ncap < 4 {
        ncap = 4
    }
    nval := reflect.MakeSlice(val.Type(), n, ncap)
    reflect.Copy(nval, val)
    val.Set(nval)
}
val.SetLen(n + 1)
// ...
val.Index(n).SetString("value") // Depends on type

这段文字摘自我一段时间之前写的一个库github.com/webconnex/xmlutil,具体是decode.go文件。


嘿,谢谢。我已经弄清楚了(有点急于发帖提问:D)。 - joshlf
@joshlf13 我注意到你问了一些关于 reflect 的问题。请查看上面链接的 xmlutil,以及其他编码包。它们应该会对你有所帮助。 - Luke
好的,我会做。顺便说一句,如果你感兴趣的话,我使用反射的原因是我正在编写一个名为“illegal”的包,它提供了执行技术上不允许的操作的函数(例如通用Map函数、比较两个函数指针等)。目前这是一个私有仓库在Github上(还没有准备好投入生产),但如果你有兴趣贡献代码,我很乐意接受帮助。 - joshlf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接