检查变量实现接口而无需编译 [英] Checking of variable implements interface without compiling

查看:52
本文介绍了检查变量实现接口而无需编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道具体类型是否实现特定接口并打印出来.我已经编写了一个示例[0],它带有一个自定义结构(MyPoint),而不是接口类型.MyPoint具有io.Reader接口中定义的Read功能:

I want to know whether a concrete type implements a specefic interface and print it out. I have written an example [0] with a self defined struct (MyPoint) beeing not an interface-type. MyPoint has the function Read as defined in the interface of io.Reader:

type MyPoint struct {
   X, Y int
}

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

目的是获得有关具体类型p实现接口io.Writer的信息.因此,我写了一个简短的主要摘要以了解支票的真实性.

The aim is to get the information that the concrete type p implements the interface io.Writer. Therefore I have written a short main trieng to get a true for the check.

func main() {
     p := MyPoint{1, 2}
}

第一个想法是在反射和类型开关的帮助下进行检查,然后将 check(p)添加到主功能中.

The first idea was to check it with the help of reflection and a type-switch and adding check(p) to to the main-function.

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类型不同.

The output is: p is of type MyPoint. After a bit of research I know that I should have expected that because Go's types are static and therefore the type of p is MyPoint and not io.Reader. In addition to that io.Reader is an interface-type which is different to type MyPoint.

我找到了一种解决方案,例如在[1]处,它在编译时检查MyPoint是否可以是io.Reader.有用.

I found one solution e.g. at [1] which checks whether MyPoint can be an io.Reader at compile time. It works.

var _ io.Reader = (*MyPoint)(nil)

但这不是我想要的解决方案.像下面这样的尝试也失败了.我认为是由于上述原因,不是吗?

But that isn't the solution I wanted. Tries like below fails, too. I think it's because of the reason above, isn't it?

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是否在不编译的情况下实现了接口?我希望有人能帮助我.

Exists one solution to check whether p implements the interface without compiling? I hope that someone can help me.

[0] http://play.golang.org/p/JCsFf7y74C (固定的) http://play.golang.org/p/cIStOOI84Y (旧)

[0] http://play.golang.org/p/JCsFf7y74C (fixed) http://play.golang.org/p/cIStOOI84Y (old)

[1] 说明值是否实现了接口.Golang

推荐答案

使用反射包完全可以做您想做的事情.这是一个示例:

It is perfectly possible to do what you want with the reflect package. Here is an example:

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
}

棘手的一点是要注意如何处理指针.

The tricky point is to pay attention to how pointers are handled.

这篇关于检查变量实现接口而无需编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆