【问题标题】:Getting and setting length of arbitrary slice获取和设置任意切片的长度
【发布时间】:2020-03-19 15:38:13
【问题描述】:

要获取任何切片的长度,我使用reflect.ValueOf(slice).Len()。 要设置任何切片的长度,我使用reflect.ValueOf(&slice).Elem().SetLen(n)

我的结构中有一个reflect.Value 类型的字段,值设置为reflect.ValueOf(&slice),以便我可以更改切片。但现在我无法获得底层切片的长度。

如果我直接打电话给Len(),它会因为call of reflect.Value.Len on ptr Value而恐慌,如果我打电话给Elem().Len(),它会因为call of reflect.Value.Len on interface Value而恐慌。

下面是我试图实现的功能:

func pop(slice interface{}) interface{} {
    v := reflect.ValueOf(slice)
    length := v.Len()
    last := v.Index(length - 1)
    v.SetLen(length - 1)
    return last
}

我怎样才能同时使用切片指针的refect.Value

【问题讨论】:

  • 听起来你的slice 实际上并不是一个切片。它看起来像是切片周围的某种接口包装器。
  • 是的,我忘了提到切片存储在 interface{} 类型的参数中。
  • @iLoveReflection 谢谢。已更新。

标签: go


【解决方案1】:

编写函数以使用指向切片参数的指针。

// pop removes and returns the last element from
// the slice pointed to by slicep.
func pop(slicep interface{}) interface{} {
    v := reflect.ValueOf(slicep).Elem()
    length := v.Len()
    last := v.Index(length - 1)
    v.SetLen(length - 1)
    return last
}

这样称呼它:

slice := []int{1, 2, 3}
last := pop(&slice)
fmt.Println(last)  // prints 3
fmt.Println(slice) // prints [1 2]

Run it on the playground

【讨论】:

    猜你喜欢
    • 2016-08-26
    • 2016-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-02
    • 2018-02-15
    • 1970-01-01
    • 2012-08-29
    相关资源
    最近更新 更多