“非侵入式”接口的实现原理
主要用法
(1)从类型赋值到接口
(2)接口查询
(3)接口之间赋值
(1)类型赋值给接口
例子
package main
import "fmt"
type ISspeaker interface{
Speak()
}//接口
type SimpleSpeaker struct{
Message string
}//类型
func (speaker *SimpleSpeaker) Speak() {
fmt.Println("I am speaking?",speaker.Message)
}//类型实现了接口中的函数
func main(){
var speaker ISspeaker//接口类型,但是可以当作SimpleSpeaker来用了
speaker = &SimpleSpeaker{"Hell"}
speaker.Speak()
}
实现的核心问题:
如何从机器的角度判断一个SimpleSpeaker类型实现了ISpeaker接口的所有方法?
(1)获取类型的所有方法集合(A)
(2)获取接口的所有方法集合(B)
(3)判断B是否是A的子列
可以在编译期就完成所有的任务
接口查询
使用场景:
拿着IReader接口的开发者在某些时候想知道IReader所对应的类型是否也实现了IReadWriter接口,这样他就可以切换到IReadeWriter接口,然后调用该接口的write()方法写入数据
查询方式如下
var reader Ireader = NewReader()
if write,ok:=reader.(IReadWriter);ok{
write.Write()
}
接口查询其实就是在做接口方法查询,只要该类型实现了某个接口的所有方法,就可以认为该类型实现了此接口。
只能在运行期进行老老实实的借口匹配
接口赋值
将一个接口直接赋值给另外一个接口
var rw IReadWriter = ...
var r IReader = rw
...
可以将IReadWriter对象给IReader,但是不能够反过来
编译器可以完成,所以相对于接口查询消耗比较小