英文:
Set slice index using reflect in Go
问题
我在Go语言中使用reflect.Value表示一个切片。我有以下代码:
slice := reflect.MakeSlice(typ, len, cap)
如果我想从slice
中获取第i个值,很简单:
v := slice.Index(i) // 返回一个reflect.Value
然而,我似乎找不到一种方法来设置第i个值。reflect.Value
有很多的setter方法,例如,如果我有一个映射m
,可以这样做:
m.SetMapIndex(key, value) // key和value的类型为reflect.Value
但是对于切片似乎没有类似的方法。我想到的一个可能是,也许从slice.Index(i)
返回的值实际上是一个指针,所以调用v := slice.Index(i); v.Set(newV)
会起作用?我不确定。有什么想法吗?
英文:
I'm in Go, working with a reflect.Value representation of a slice. I have the following:
slice := reflect.MakeSlice(typ, len, cap)
If I want to get the ith value from slice
, it's simple:
v := slice.Index(i) // returns a reflect.Value
However, I can't seem to find a way to <i>set</i> the ith value. reflect.Value
has lots of setter methods, for example, if I had a map, m
, the following is possible:
m.SetMapIndex(key, value) // key and value have type reflect.Value
But there doesn't seem to be an equivalent for slices. My one thought was that maybe the value returned from slice.Index(i)
is actually a pointer somehow, so calling v := slice.Index(i); v.Set(newV)
would work? I'm not sure. Ideas?
答案1
得分: 25
搞定了!原来我提前发布了这个问题 - 我猜测 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 上的可运行代码)
英文:
Figured it out! Turns out I posted this prematurely - my guess that slice.Index(0)
returns a pointer was correct. In particular:
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())
prints:
0
1
1
(Here's runnable code on the go playground)
答案2
得分: 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") // 取决于类型
这段代码摘自我一段时间前编写的一个库 github.com/webconnex/xmlutil,具体是 decode.go 文件。
英文:
This might help:
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
Taken from a library I wrote a while back github.com/webconnex/xmlutil, specifically decode.go.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论