亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用反射提取接口類型名稱和包?

如何使用反射提取接口類型名稱和包?

Go
鳳凰求蠱 2021-11-15 17:08:31
我需要使用反射知道類型名稱及其路徑。typeType有 Name() 和 PkgPath() 方法,但如果類型是接口,它們都返回空。但是,如果我反映一個函數并提取其參數的類型信息,我會得到正確的類型信息。我應該假設這是前一種情況下的錯誤嗎?無論上下文如何(例如類型函數參數或值的類型),TypeOf 不應該返回相同的類型信息嗎?我知道類型斷言,但我并不總是有一個值來進行斷言,所以我需要使用reflect.Type 信息。package mainimport (    "fmt"    "reflect"    "golang.org/x/net/context")func main() {    c := reflect.TypeOf(withValue(""))    fn := func(context.Context){}    fc := reflect.TypeOf(fn).In(0)    fmt.Println(isContext(c),  isContext(fc), c, fc)}func isContext(r reflect.Type) bool {    return r.PkgPath() == "golang.org/x/net/context" && r.Name() == "Context"}func withValue(v interface{}) context.Context {    return context.WithValue(context.TODO(), "mykey", v)}印刷false true *context.valueCtx context.Context
查看完整描述

2 回答

?
森欄

TA貢獻1810條經驗 獲得超5個贊

這是一些工作代碼:https : //play.golang.org/p/ET8FlguA_C


package main


import (

    "fmt"

    "reflect"

)


type MyInterface interface {

    MyMethod()

}


type MyStruct struct{}


func (ms *MyStruct) MyMethod() {}


func main() {

    var structVar MyInterface = &MyStruct{}

    c := reflect.TypeOf(structVar)


    fn := func(MyInterface) {}

    fc := reflect.TypeOf(fn).In(0)


    fmt.Println(isMyInterface(c), isMyInterface(fc), c, fc)

    // OP expects : "true true main.MyInterface main.MyInterface"

}


func isMyInterface(r reflect.Type) bool {

    // TypeOf trick found at https://groups.google.com/forum/#!topic/golang-nuts/qgJy_H2GysY

    return r.Implements(reflect.TypeOf((*MyInterface)(nil)).Elem())

}

這是我在找到實際解決方案之前的答案reflect。我會放在這里,因為我認為它仍然有一些有趣的部分。


首先要做的事情是: for c、 r.PkgPath() 和 r.Name() 是空的,因為底層類型是指針 ( *context.valueCtx)。


要解決這個問題,您可以使用 c := reflect.Indirect(reflect.ValueOf(withValue(""))).Type()


但這并不isContext(c)成立,因為你有r.PkgPath() == "golang.org/x/net/context" && r.Name() == "valueCtx".


檢查 var 是否實現接口的最佳方法是刪除反射并使用這樣的類型斷言:


https://play.golang.org/p/td1YaHHej9


package main


import "fmt"


type MyInterface interface {

    MyMethod()

}


type MyStruct struct{}


func (ms *MyStruct) MyMethod() {}


func main() {

    var structVar MyInterface = &MyStruct{}


    fmt.Println(isMyInterface(structVar))

}


func isMyInterface(object interface{}) bool {

    _, ok := object.(MyInterface)

    return ok

}

您的代碼使用函數參數按預期工作,因為沒有基礎值,因此reflect使用接口類型。但是對于任何具體的 var,它將使用值的實際類型。


查看完整回答
反對 回復 2021-11-15
?
慕虎7371278

TA貢獻1802條經驗 獲得超4個贊

golang 中有兩種接口,即eface和iface。而 eface 是一個空接口,可以簡單地表示為interface {}. iface 是一種至少具有一種方法的接口,例如:


type MyInterface interface {

    Greeting() string

}

在 golang 實現中,eface 和 iface 都是兩個字長的結構體。eface 保存數據和數據類型,iface 保存數據、接口類型和數據類型。當 iface 分配給 eface 時,將忽略 interfacetype 信息。只有傳遞給 eface 的數據和數據類型。


因此,reflect.TypeOf(i interface{})的參數是和 eface,沒有接口類型信息(在您的情況下也稱為 context.Context)。所以你不能得到原始的接口類型。


查看完整回答
反對 回復 2021-11-15
  • 2 回答
  • 0 關注
  • 194 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號