Go 编译器自动检测类型是否实现接口

Go 编译器自动检测类型是否实现接口

开源库里会有一些类似下面这种奇怪的用法:

1
var _ io.Writer = (*myWriter)(nil)

这时候会有点懵,不知道作者想要干什么,实际上这就是此问题的答案。编译器会由此检查 *myWriter 类型是否实现了 io.Writer 接口。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import "io"

type myWriter struct {

}

/*func (w myWriter) Write(p []byte) (n int, err error) {
return
}*/

func main() {
// 检查 *myWriter 类型是否实现了 io.Writer 接口
var _ io.Writer = (*myWriter)(nil)

// 检查 myWriter 类型是否实现了 io.Writer 接口
var _ io.Writer = myWriter{}
}

注释掉为 myWriter 定义的 Write 函数后,运行程序:

1
2
3
4
5
# command-line-arguments
src/learn/tongbu/tongbu.go:14:6: cannot use (*myWriter)(nil) (type *myWriter) as type io.Writer in assignment:
*myWriter does not implement io.Writer (missing Write method)
src/learn/tongbu/tongbu.go:17:6: cannot use myWriter{} (type myWriter) as type io.Writer in assignment:
myWriter does not implement io.Writer (missing Write method)

报错信息:*myWriter/myWriter 未实现 io.Writer 接口,也就是未实现 Write 方法。

解除注释后,运行程序不报错。

实际上,上述赋值语句会发生隐式地类型转换在转换的过程中,编译器会检测等号右边的类型是否实现了等号左边接口所规定的函数。

总结: 可通过在代码中添加类似如下的代码,用来检测类型是否实现了接口:

1
2
var _ io.Writer = (*myWriter)(nil)
var _ io.Writer = myWriter{}