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

5

我收到的接口基本上是一个切片。现在我想将其转换为指向该切片的指针。问题在于,我只有切片本身或指向接口的指针。

我可以很容易地通过代码示例来说明:

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

我需要的是这种类型:
fmt.Println(reflect.TypeOf(result))    // this should be type *[]int

我只能在运行时知道类型,因此无法仅使用&(model.([]int))

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

编辑:
为了使问题更清晰,我应该补充说明:我对切片的数据不感兴趣,但只对获取相同类型切片的指针感兴趣(基本上可以为空)。因此 James Henstridge 的答案完全适用。


http://golang.org/pkg/reflect/#Value.Addr 有什么问题吗?我承认我不明白你真正想做什么。这取决于具体情况。在Go中,并非所有值都是可寻址的,因此可能无法实现。你想用 *[]int 做什么? - Volker
确实,这个值是不可寻址的。 基本上我想创建一个预定义类型的切片(使用reflect.MakeSlice),并将其传递给库mgo的方法(mgo的Query的All()方法)。这个方法需要一个指向切片的Ptr。我找到了一种解决方案,即在已知类型的情况下在外部创建切片。但我正在尝试找到一种在内部以通用方式完成此操作的方法。 我理解得对吗?由于它不是可寻址的值,所以这是不可能的吗? - Chrisport
在Go语言中,所有东西都是按值传递的。在将值复制到“方法”调用中之后,您无法获取对“model”的指针。无论它是否为“interface {}”,您都有一个切片值,而不是指针。 - JimB
1
补充JimB的评论,切片在某种程度上像指针,因为它们引用一些内存块,并且更改切片的元素会更改内存,因此您可以在调用者中看到它,但是切片变量本身不能更改,因为它作为值传递。切片变量包含对底层内存的指针以及切片的长度和容量。 - andlabs
1个回答

6
在尝试回答这个问题之前,值得回过头来问一下,你想要的*[]int值应该指向什么?
考虑到方法的调用方式,我们不可能从调用上下文中获取到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 方法,并相应地采取行动。


这是反射包的一个很好的使用。 - Drew
谢谢,这个完美地运行了!我基本上对切片数组的内容不感兴趣(在我的用例中它总是为空),但只关心获取相同类型的切片和指向它的指针。 - Chrisport

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接