繁体   English   中英

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

[英]How to get the pointer to a struct passed through interface{} in golang?

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

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

我想调用方法Tt但失败了,因为该变量在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..
}

使用反射:

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

传入Tinterface ,然后可以得到*Tinterface

要调用指针方法Tt() ,您必须具有*A (或采用可寻址 A值的地址)。 变量bA值不可寻址 ,因此无法通过b访问A指针方法。

解决方法是从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)
}

在呼叫reflect.ValueOf(v)在值v被作为参数传递。 ValueOf函数将空接口ValueOf以恢复类型A的值。

在调用reflect.ValueOf(&v)*interface{}存储在空接口中,然后将其作为参数传递。 ValueOf函数将空接口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")
}

您只需要键入强制类型转换。 例:

type SomeStruct1 struct{
    someList []string
}

func (s *SomeStruct1) print() {
    fmt.Printf("%v\n", s.someList)
...

func Call(T interface{}){
    switch T.(type){
    case *SomeStruct1:
        t := T.(*SomeStruct1) // cast as pointer to struct
        t.print()
    ...
    }
}

func main() {
    a := SomeStruct{
        someList: []string{"a", "b"}
    }
    Call(&a) // pass a as ptr
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM