如何让编译器自动检测类型是否实现了接口
经常看到一些开源库里会有一些类似下面这种奇怪的用法:
var _ io.Writer = (*myWriter)(nil)
1
这时候会有点懵,不知道作者想要干什么,实际上这就是本节问题的答案。编译器会由此检查 *myWriter
类型是否实现了 io.Writer 接口。
来看一个例子:
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{}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
注释掉为 myWriter 定义的 Write 函数后,运行程序:
src/main.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/main.go:15:6: cannot use myWriter literal (type myWriter) as type io.Writer in assignment:
myWriter does not implement io.Writer (missing Write method)
1
2
3
4
2
3
4
报错信息: *myWriter/myWriter
未实现 io.Writer 接口,也就是未实现 Write 方法。要知道例 子中并没有直接调 Write 方法,所以是 “var _ io.Writer = (*myWriter)(nil)” 这种写法让编译器进行了类型检查。
解除注释后,运行程序不报错。
实际上,上述赋值语句会发生隐式地类型转换,在转换的过程中,编译器会检测等号右边的类 型是否实现了等号左边接口所定义的函数。
总结一下,可通过在代码中添加类似如下的代码,用于检测类型是否实现了接口:
var _ io.Writer = (*myWriter)(nil)
var _ io.Writer = myWriter{}
1
2
2
上次更新: 7/12/2024, 2:37:05 PM