我想知道具体类型是否实现了一个specefic接口并将其打印出来。 我编写了一个带有自定义结构(MyPoint)的示例[0],而不是接口类型。 MyPoint具有io.Reader接口中定义的Read函数:
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 is of type 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] http://play.golang.org/p/JCsFf7y74C(已修复) http://play.golang.org/p/cIStOOI84Y(旧)
[1] Explanation of checking if value implements interface. Golang
答案 0 :(得分:7)
使用反射包完全可以做到你想要的。这是一个例子:
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
}
棘手的一点是要注意如何处理指针。
答案 1 :(得分:4)
存在一个解决方案来检查p是否在没有编译的情况下实现接口?
是:仔细阅读代码: - )
怎么可能呢?如果p的方法集覆盖i,则p实现一些接口i。您将始终必须编译代码。
我假设您希望在编译期间不会失败,而只是在运行时打印。
诀窍是获得一个非零接口类型,可以使用Implements
的{{1}}方法进行测试:
reflect.Type