簡體   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