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

huangapple go评论72阅读模式
英文:

Assign result of reflect.AppendSlice to pointer

问题

我遇到了一些困难,无法将这段代码转换为一个接受interface{}作为输入参数的更通用的版本,该代码实际上是对一个切片进行左旋转。

我在最后的赋值语句上遇到了问题:

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 =将会将右侧的值赋给指针指向的空间。然而,我的AppendSlice调用返回的是Value类型。我不确定类型断言应该在哪里进行,我猜应该在左侧进行断言操作?

英文:

I have troubles translating this piece of code, which is effectively a left rotate on a slice, into a more generic version which accepts interface{} as an input parameter.

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

I have troubles with the final assignment:

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)
}

The error message is invalid indirect of a (type {}). The value of a is interface{}, hence *a = would be to assign the right-hand value to the space where the pointer is pointing to. My call to AppendSlice returns Value though. I am not sure where the type assertion needs to happen, I suppose on the left-hand side?

答案1

得分: 1

在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)


以下是使用reflect包实现rotate的方法。

使用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"}
rotateSlice(&a, 2)

在playground上运行所有示例

英文:

Eliminate the use of the reflect package in Go 1.18 and later by using generics:

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

Call it like this: x = rotateSlice(x, 2)


Here's now to implement rotate using the reflect package.

Use Value.Set to set the value in the slice.

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))
}

Call the function with a pointer to a slice:

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

Run all of the examples on the playground.

答案2

得分: 1

a是一个interface{}而不是指针,所以你不能对其进行解引用操作。即使你有一个指向切片的指针,你也不能将reflect.AppendSlice的结果赋值给它,因为它返回的是reflect.Value类型。你需要通过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))
}

你可以在这里查看示例代码:https://play.golang.org/p/JCF8jsRJ_O

英文:

a is an interface{} not a pointer, so you can't dereference it. Even if you have a pointer to a slice, you can't assigned the result ofreflect.AppendSlice, because it returns the type reflect.Value. You need to set the value via 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))
}

huangapple
  • 本文由 发表于 2016年10月25日 01:00:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/40223698.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定