douhu3424 2015-08-20 08:45
浏览 43
已采纳

检查变量实现接口而无需编译

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
}

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}
}

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
")
    case MyPoint:
        fmt.Printf("p is of type MyPoint
")
    default:
        fmt.Println("p is unknown.")
    }
}

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.

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 
", pType.Implements(readerType))

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 (fixed) http://play.golang.org/p/cIStOOI84Y (old)

[1] Explanation of checking if value implements interface. Golang

  • 写回答

2条回答 默认 最新

  • duanhuanyou6478 2015-08-20 09:43
    关注

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 关于线性结构的问题:希望能从头到尾完整地帮我改一下,困扰我很久了
  • ¥20 设计一个二极管稳压值检测电路
  • ¥15 内网办公电脑进行向日葵
  • ¥15 如何输入双曲线的参数a然后画出双曲线?我输入处理函数加上后就没有用了,不知道怎么回事去掉后双曲线可以画出来
  • ¥50 WPF Lidgren.Network.Core2连接问题
  • ¥15 soildworks装配体的尺寸问题
  • ¥100 有偿寻云闪付SDK转URL技术
  • ¥30 基于信创PC发布的QT应用如何跨用户启动后输入中文
  • ¥20 非root手机,如何精准控制手机流量消耗的大小,如20M
  • ¥15 远程安装一下vasp