【问题标题】:Set slice index using reflect in Go在 Go 中使用反射设置切片索引
【发布时间】:2013-08-09 13:28:31
【问题描述】:

我在 Go 中,使用切片的 reflect.Value 表示。我有以下内容:

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

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

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

但是,我似乎找不到设置第 i 个值的方法。 reflect.Value 有很多 setter 方法,例如,如果我有一个地图,m,以下是可能的:

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

但似乎没有切片的等价物。我的一个想法是,也许从slice.Index(i) 返回的值实际上是一个指针,所以调用v := slice.Index(i); v.Set(newV) 会起作用吗?我不知道。想法?

【问题讨论】:

    标签: reflection go slice


    【解决方案1】:

    想通了!原来我过早地发布了这个——我猜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
    

    (这里是 runnable code 在游乐场)

    【讨论】:

      【解决方案2】:

      这可能会有所帮助:

      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)。
      • @joshlf13 我注意到你问了几个reflect 问题。查看上面链接的xmlutil,以及其他一些编码包。他们应该能帮上大忙。
      • 好的,会的。顺便说一句,如果你有兴趣,我经常使用反射的原因是我正在编写一个名为“非法”的包,它提供了执行技术上不允许的操作的函数(如通用 Map 函数,比较两个函数指针,等等)。目前它是 github 上的一个私人仓库(尚未准备好投入生产),但如果您有兴趣贡献,我很乐意提供帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-20
      • 1970-01-01
      • 2019-01-02
      • 1970-01-01
      • 1970-01-01
      • 2019-02-21
      • 2017-07-06
      相关资源
      最近更新 更多