golang的interface的使用以及作用
检测是否实现接口
// 检查 *myWriter 类型是否实现了 io.Writer 接口
var _ io.Writer = (*myWriter)(nil)
// 检查 myWriter 类型是否实现了 io.Writer 接口
var _ io.Writer = myWriter{}
指针实现和值实现
//必须是指针才可使用
func (w *Woman) Say() {
fmt.Println("I'm a woman")
}
//指针和值都可以使用
func (m Man) Say() {
fmt.Println("I'm a man")
}
防止或者解决包相互依赖的情况
-
情况说明
- 当你a、b两个包都需要相互使用各自内部的函数、结构体的时候,就会形成包相互依赖的情况
-
解决方法:
- 新开一个文件夹c,定义一个interface的接口,随便选择其中一个包,比如我们选择a包,让a这个包里面需要用到b包的函数方法都写入到interface中,让a包导入c包,然后通过接口来使用b包中的方法,这样就不需要导入b包了
-
示例:
- 使用接口前,可以看出现在就是互相导入的情况了
//Room.go package modelroom import "....../modelclient" type Room struct { RoomID string PlayerList map[string]*modelclient.Client StatesList map[string]*calculate.StateController //管理地图的状态 RoomMapManager *Map.MapManager IsGameBegin bool IsGameEnd bool EndChan chan struct{} //用于数据转发 DataChan chan map[string]interface{} FilterableDataChan chan FilterableData // 限制清除房间的goroutine只有一个 ifClearing bool RoomLock sync.RWMutex logger *zap.Logger } //client.go package modelclient import "....../modelroom" type Client struct { UserID string //玩家标识的颜色 UserColor int Room *modelroom.Room Conn *websocket.Conn StateController *calculate.StateController //用于判断此玩家当前是否在线 IsInGame bool //用于判断此玩家是否已经注册到hub中 logger *zap.Logger dataChan chan []byte }
- 使用接口后,就不会有相互导入的情况了
//roomcontroller.go package roomcontroller type RoomController interface { Lock() Unlock() GetChannelWithoutFilter() chan<- map[string]interface{} GetChannelWithFilter() chan<- filter.FilterableData GetEndChannel() chan<- struct{} //查看游戏是否结束 CheckEnd() bool //返回IsGameBegin GetIsGameBegin() bool //返回IsGameEnd GetIsGameEnd() bool //清理倒计时 CountTimeClear() GetStateController(id string) (*calculate.StateController, error) GetRoomManager() (*Map.MapManager, error) HandlePlayerClose(id string) error } //Room.go,Room结构体已经实现了RoomController的接口 package modelroom import "....../modelclient" type Room struct { RoomID string PlayerList map[string]*modelclient.Client StatesList map[string]*calculate.StateController //管理地图的状态 RoomMapManager *Map.MapManager IsGameBegin bool IsGameEnd bool EndChan chan struct{} //用于数据转发 DataChan chan map[string]interface{} FilterableDataChan chan FilterableData // 限制清除房间的goroutine只有一个 ifClearing bool RoomLock sync.RWMutex logger *zap.Logger } //client.go package modelclient import "....../roomcontroller" type Client struct { UserID string //玩家标识的颜色 UserColor int RoomController roomcontroller.RoomController Conn *websocket.Conn StateController *calculate.StateController //用于判断此玩家当前是否在线 IsInGame bool //用于判断此玩家是否已经注册到hub中 logger *zap.Logger dataChan chan []byte hubManger hubmanager.HubManager }
变量私有化以及实现构造器
- 接口本身不能创建实例,但是可以指向实现了接口的变量,这样可以实现动态绑定
package example type A interface { ID() string } //结构体小写,因此外包是无法使用这个结构体 type a struct { id string } //通过接口来接收widget的实例,这样就不会暴露实例,用户只能通过这个NewWidget才可以获取到实例,就实现了构造器的思想 func New_a() A { return a{ id: xid.New().String(), } } //实现接口 func (ins a) ID() string { return ins.id }
Comments are closed