将 reflect.AppendSlice 的结果分配给指针

Assign result of reflect.AppendSlice to pointer

我无法将这段代码(实际上是对切片进行左旋转)翻译成接受 interface{} 作为输入参数的更通用的版本。

func rotate(a *[]int, i int) {
    x, b := (*a)[:i], (*a)[i:]
    *a = append(b, x...)
}

我对期末作业有困难:

func rotateSlice(a interface{}, i int) {
    v := reflect.ValueOf(a)
    x, b := v.Elem().Slice(0, i), v.Elem().Slice(i, v.Elem().Len())
    *a = reflect.AppendSlice(b, x)
}

错误信息是invalid indirect of a (type {})a 的值是 interface{},因此 *a = 将把右边的值赋给指针指向的 space。不过我打电话给 AppendSlice returns Value。我不确定类型断言需要在哪里发生,我想是在左侧?

通过使用泛型消除 Go 1.18 及更高版本中 reflect 包的使用:

func rotateSlice[T any](a []T, i int) []T {
    x, b := a[:i], a[i:]
    return append(b, x...)
}

这样称呼它:x = rotateSlice(x, 2)


下面是使用反射包实现旋转。

使用Value.Set设置切片中的值。

func rotateSlice(a interface{}, i int) {
    v := reflect.ValueOf(a).Elem()
    x, b := v.Slice(0, i), v.Slice(i, v.Len())
    v.Set(reflect.AppendSlice(b, x))
}

使用指向切片的指针调用函数:

a := []string{"a", "b", "c", "d"}
roateSlice(&a, 2)

Run all of the examples on the playground.

a 是一个 interface{} 而不是指针,所以你不能取消引用它。即使你有一个指向切片的指针,你也不能分配 reflect.AppendSlice 的结果,因为它 returns 类型 reflect.Value。您需要通过 Value.Set 设置值。

https://play.golang.org/p/JCF8jsRJ_O

func rotateSlice(a interface{}, i int) {
    v := reflect.ValueOf(a).Elem()
    x, b := v.Slice(0, i), v.Slice(i, v.Len())
    v.Set(reflect.AppendSlice(b, x))
}