Reflection 在不编译的情况下检查变量实现接口

Reflection 在不编译的情况下检查变量实现接口,reflection,go,interface,Reflection,Go,Interface,我想知道具体类型是否实现了specefic接口并将其打印出来。 我编写了一个示例[0],其中的自定义结构(MyPoint)不是接口类型。MyPoint具有io接口中定义的读取功能。读卡器: type MyPoint struct { X, Y int } func (pnt *MyPoint) Read(p []byte) (n int, err error) { return 42, nil } 目的是获取具体类型p实现接口io.Writer的信息。 因此,我写了一个简短的主

我想知道具体类型是否实现了specefic接口并将其打印出来。 我编写了一个示例[0],其中的自定义结构(MyPoint)不是接口类型。MyPoint具有io接口中定义的读取功能。读卡器:

type MyPoint struct {
   X, Y int
}

func (pnt *MyPoint) Read(p []byte) (n int, err error) {
    return 42, nil
}
目的是获取具体类型p实现接口io.Writer的信息。 因此,我写了一个简短的主要三年来得到一个真正的检查

func main() {
     p := MyPoint{1, 2}
}
第一个想法是借助反射和类型开关来检查它,并在主函数中添加
check(p)

func checkType(tst interface{}) {
    switch tst.(type) {
    case nil:
        fmt.Printf("nil")
    case *io.Reader:
        fmt.Printf("p is of type io.Reader\n")
    case MyPoint:
        fmt.Printf("p is of type MyPoint\n")
    default:
        fmt.Println("p is unknown.")
    }
}
输出为:
p的类型为MyPoint
。经过一点研究,我知道我应该预料到这一点,因为Go的类型是静态的,因此p的类型是MyPoint而不是io.Reader。除此之外,io.Reader是一种不同于MyPoint类型的接口类型

我找到了一个解决方案,例如在[1]检查MyPoint是否可以在编译时作为io.Reader。它起作用了

var _ io.Reader = (*MyPoint)(nil)
但这不是我想要的解决方案。像下面这样的尝试也失败了。我想这是因为上面的原因,不是吗

i := interface{}(new(MyPoint))
    if _, ok := i.(io.Reader); ok {
        fmt.Println("i is an io.Reader")
}
pType := reflect.TypeOf(p)
if _, ok := pType.(io.Reader); ok {
    fmt.Println("The type of p is compatible to io.Reader")
}

readerType := reflect.TypeOf((*io.Reader)(nil)).Elem()
fmt.Printf("p impl. Reader %t \n", pType.Implements(readerType))
是否存在一个解决方案来检查p是否在不编译的情况下实现接口?我希望有人能帮助我

[0](固定) (旧)


[1]

使用reflect软件包,您完全可以随心所欲。以下是一个例子:

package main

import (
    "fmt"
    "io"
    "reflect"
)

type Other int

type MyPoint struct {
    X, Y int
}

func (pnt *MyPoint) Read(p []byte) (n int, err error) {
    return 42, nil
}

func check(x interface{}) bool {
    // Declare a type object representing io.Reader
    reader := reflect.TypeOf((*io.Reader)(nil)).Elem()
    // Get a type object of the pointer on the object represented by the parameter
    // and see if it implements io.Reader
    return reflect.PtrTo(reflect.TypeOf(x)).Implements(reader)
}

func main() {

    x := MyPoint{0, 0}
    y := Other(1)

    fmt.Println(check(x)) // true
    fmt.Println(check(y)) // false
}
棘手的一点是要注意如何处理指针

是否存在一个解决方案来检查p是否在不编译的情况下实现接口

是:仔细阅读代码:-)

这怎么可能呢?如果p的方法集覆盖i,则p实现一些接口i。您必须始终编译代码

我假设您不希望在编译期间失败,而希望在运行时打印。 诀窍是获得一个非nil接口类型,可以使用
reflect.type的
Implements
方法对其进行测试:

pt := reflect.TypeOf(&MyPoint{})
ioReaderType := reflect.TypeOf((*io.Reader)(nil)).Elem()
fmt.Println(pt.Implements(ioReaderType))  //  ==> true

只做
有什么错吗?\uuu,好:=x.(io.Reader)
?如果
x
实现了
io.Reader
,则
ok
为真,否则为假。编辑“fixed”[0]链接使其工作