如何获取golang中通过interface{}传递的结构体指针?

use*_*011 6 pointers interface go

不,我不认为这与 如何确定接口{}值的“真实”类型?。我知道如何获取接口变量的类型,但我找不到获取指向 interface{} 真实类型的指针的方法。

最近,我遇到了麻烦interface{}。我有一个类型为 A 的变量被传递interface{},一个方法Tt被定义为 *A 作为接收者。

我想调用该方法Tt但失败了,因为该变量位于 an 中interface{},并且我无法获取指向该变量的指针。

正如您所看到的,reflect.TypeOf(v)给出了正确的类型A,但reflect.TypeOf(&v)给出的*interface {}*A

有什么办法可以得到吗*A

package main

import (
    "fmt"
    "reflect"
)

type SomeStruct1 struct{
}

type SomeStruct2 struct{
}

type SomeStruct3 struct{
}
etc...

func (*SomeStruct1) SomeMethod(){
    fmt.Println("hello")
}
func (*SomeStruct2) SomeMethod(){
    fmt.Println("hello")
}
func (*SomeStruct3) SomeMethod(){
    fmt.Println("hello")
}
etc...

func DoSomething(arg interface{}){
    switch v:=b.(type){
        []byte:{
            dosomething for []byte
        }
        default:{
            var m reflect.Value
            if value.Kind() != reflect.Ptr {
                m = reflect.ValueOf(&v).MethodByName("SomeMethod")
            } else {
                m = reflect.ValueOf(v).MethodByName("SomeMethod")
            }
            m.Call(nil)
        }
}

func main() {
    DoSomething([]byte{...})
    DoSomething(SomeStruct1{})
    DoSomething(&SomeStruct1{})
    etc..
}
Run Code Online (Sandbox Code Playgroud)

sha*_*awn 8

使用反射:

//
// Return a pointer to the supplied struct via interface{}
//
func to_struct_ptr(obj interface{}) interface{} {
    vp := reflect.New(reflect.TypeOf(obj))
    vp.Elem().Set(reflect.ValueOf(obj))
    return vp.Interface()
}
Run Code Online (Sandbox Code Playgroud)

传入一个interfacewith T,然后你可以得到一个interfacewith*T


Cer*_*món 3

要调用指针方法Tt(),必须有一个(或取可寻址*A值的地址)。变量中的值不可寻址因此无法通过 访问指针方法。 AAbAb

修复方法是从以下地址开始a

var a A
var b interface{}
b = &a // Note change on this line
switch v := b.(type) {
default:
    reflect.ValueOf(v).MethodByName("Tt").Call(nil)
}
Run Code Online (Sandbox Code Playgroud)

在调用中reflect.ValueOf(v), in 的值v作为参数传递。该ValueOf函数解压空接口以恢复类型的值A

在 call 中reflect.ValueOf(&v), an*interface{}存储在空接口中,然后作为参数传递。该ValueOf函数解压空接口以恢复类型的值*interface{}。这是变量的地址v,而不是变量的地址a

在这个具体示例中不需要反射:

var a A
var b interface{}
b = &a
switch v := b.(type) {
case interface {
    Tt()
}:
    v.Tt()
default:
    fmt.Println("not handled")
}
Run Code Online (Sandbox Code Playgroud)