将interface{}转换为*[]int在golang中。

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

Convert interface{} to *[]int in golang

问题

我收到一个基本上是切片的接口。现在我想将其转换为指向该切片的指针。问题是,我要么有切片本身,要么有一个指向接口的指针。
我可以通过一个代码示例来简单说明:

func main(){
    model := []int{1,2,3,4,5,6,7,8,10,11,133123123123}
    method(model)
}

func method(model interface{}){ 
    fmt.Println(reflect.TypeOf(model))    // 这是 []int 类型
    fmt.Println(reflect.TypeOf(&model))   // 这是 *interface{} 类型
}

我需要的是这种类型:

fmt.Println(reflect.TypeOf(result))    // 这应该是 *[]int 类型

我只在运行时知道类型,因此不能简单地使用 &(model.([]int))

有没有办法使用 Golang 的反射来实现这个?这里的 'int' 类型实际上并不重要,重要的是它是一个指向切片的指针*[]interface{} 也可以。

编辑:
为了更清楚地表达问题,我应该补充说明:我对切片的数据不感兴趣,只想获得一个指向相同类型切片的指针(该切片基本上可以是空的)。因此,James Henstridge 的答案完全适用。

英文:

I receive an interface which is basically a slice. Now I want to convert it to a pointer to the slice. The problem is, that I have either the slice itself or a Pointer to an interface.
I can easily show in a code example:

func main(){
    model := []int{1,2,3,4,5,6,7,8,10,11,133123123123}
    method(model)
}

func method(model interface{}){ 
    fmt.Println(reflect.TypeOf(model))    // this is of type []int
    fmt.Println(reflect.TypeOf(&model))   // this is of type *interface{}
}

What I need is this type:

fmt.Println(reflect.TypeOf(result))    // this should be type *[]int

I know the type only on runtime, therefore I cannot just take
&(model.([]int))

Is there a way using golang reflection to receive this? the type 'int' is here actually not important, important is, that it is a Pointer to a slice. *[]interface{} would be okay either.

Edit:
To make the question more clear, I should have added: I am not interested in the data of the slice, but only in getting a pointer to a slice of same type (which can basically be empty). Therefore James Henstridge answers works perfectly.

答案1

得分: 6

在尝试回答这个问题之前,值得思考一下你想要指向的 *[]int 值应该指向什么?

根据 method 的调用方式,我们无法从调用上下文中获取到指向 model 变量的指针,因为它只会接收到切片的副本作为参数(请注意,这是切片头的副本:底层数组是共享的)。

我们也无法获取指向传递的副本的指针,因为它被存储为一个 interface{} 变量:接口变量拥有用于存储其动态值的内存,并且在将新值分配给它时可以自由地重用它。如果可以获取动态值的指针,那么当分配不同类型的值时,这将破坏类型安全性。

如果我们制作第三个切片的副本,我们可以获得一个 *[]int 指针,但是不清楚这是否是你真正想要的:

v := reflect.New(reflect.TypeOf(model))
v.Elem().Set(reflect.ValueOf(model))
result := v.Interface()

这本质上是以类型不可知的方式编写以下代码:

v := new([]int)
*v = model
var result interface{} = v

现在,如果你真的想要指向调用上下文中的切片变量的指针,你需要确保使用指向切片的指针来调用 method,并相应地进行操作。

英文:

Before trying to answer the question, it is worth stepping back and asking what the *[]int value you're after should point at?

Given the way method is called we can't possibly get a pointer to the model variable from the calling context, since it will only receive a copy of the slice as its argument (note that this is a copy of the slice header: the backing array is shared).

We also can't get a pointer to the copy passed as an argument since it is stored as an interface{} variable: the interface variable owns the memory used to store its dynamic value, and is free to reuse it when the a new value is assigned to it. If you could take a pointer to the dynamic value, this would break type safety if a different type is assigned.

We can obtain a *[]int pointer if we make a third copy of the slice, but it isn't clear whether that's what you'd necessarily want either:

v := reflect.New(reflect.TypeOf(model))
v.Elem().Set(reflect.ValueOf(model))
result := v.Interface()

This is essentially a type agnostic way of writing the following:

v := new([]int)
*v = model
var result interface{} = v

Now if you really wanted a pointer to the slice variable in the calling context, you will need to ensure that method is called with a pointer to the slice instead and act accordingly.

huangapple
  • 本文由 发表于 2014年11月4日 04:30:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/26722655.html
匿名

发表评论

匿名网友

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

确定