Reflection 如何使用反射提取接口类型名称和包?

Reflection 如何使用反射提取接口类型名称和包?,reflection,go,Reflection,Go,我需要知道类型名及其使用反射的路径。typetype有Name()和PkgPath()方法,但如果该类型是接口,则两者都返回空 但是,如果我反映一个函数并提取其参数的类型信息,我就会得到正确的类型信息。我应该假设它是前一个案例中的一个bug吗?TypeOf是否应该返回相同的类型信息,而不考虑上下文(例如类型函数参数或值的类型) 我知道类型断言,但是我并不总是有一个值来做断言,所以我需要使用reflect.type信息 印刷品 false true *context.valueCtx contex

我需要知道类型名及其使用反射的路径。type
type
有Name()和PkgPath()方法,但如果该类型是接口,则两者都返回空

但是,如果我反映一个函数并提取其参数的类型信息,我就会得到正确的类型信息。我应该假设它是前一个案例中的一个bug吗?TypeOf是否应该返回相同的类型信息,而不考虑上下文(例如类型函数参数或值的类型)

我知道类型断言,但是我并不总是有一个值来做断言,所以我需要使用reflect.type信息

印刷品

false true *context.valueCtx context.Context

以下是一些工作代码:


以下是我在使用
reflect
找到实际解决方案之前的答案。 我把它放在这里,因为我觉得它还有一些有趣的部分


首先:对于
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是否实现接口的最佳方法是删除反射并使用如下类型断言:


由于没有基础值,因此代码与函数参数的预期效果相同,因此
reflect
使用接口类型。但对于任何具体的var,它都将使用值的实际类型。

在golang,aka中有两种接口,efaceiface。eface是一个空接口,可以简单地表示为
interface{}
。iface是一种至少有一种方法的接口,例如:

type MyInterface interface {
    Greeting() string
}
在golang实现中,eface和iface都是两个字长的结构。eface保存数据和数据类型,iface保存数据、接口类型和数据类型。当iface分配给eface时,将忽略interfacetype信息。仅传递给eface的数据和数据类型


因此,
reflect.TypeOf(i interface{})
的参数是和eface,没有interfacetype信息(在您的例子中称为context.context)。因此,您无法获取原始的interfacetype。

对于我的回答者同伴,runnable Playerd链接:
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())
}
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
}
type MyInterface interface {
    Greeting() string
}