英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论