go session接口设计
与其说本文与session有关,不如说我对接口这一概念清晰了许多,之前学接口的时候确实有些一知半解了
最近在看go session管理的时候恍然大悟
以下是定义的两个接口:
//定义Session接口,管理单个session中的内容 type Session interface { Set(key string, value interface{}) error //设置session Get(key string) (interface{}, error) //获取session Del(key string) error //删除session Save() error //保存 } //管理所有session的接口 type SessionMgr interface { SessionInit(addr string, options ...string) error CreateSession() (Session, error) SessionGet(sessionId string) (Session, error) SessionDestory(sessionId string) error SessionGC(maxLifeTime int64) }
以下是待实现接口的结构体:
type MemorySession struct { sessionId string data map[string]interface{} //存k-v键值对 rwlock sync.RWMutex //读写锁 } type MemorySessionMgr struct { sessionMap map[string]Session //保存每一个session rwlock sync.RWMutex sessionMgr SessionMgr maxLifeTime int64 }
定义session全局管理器----MemorySessionMgr的结构体方法,返回session接口变量
这里我想了很久,编译器报错了说类型对不上,我看别人的实例时发现这里实际返回的是一个结构体实例,但是返回值定义的是接口变量
起初我还不知道为什么要返回接口变量,也不知道为什么实际返回结构体实例,后来回去看看接口的实现发现,接口是通过接口变量调用接口内方法的,接口变量是由结构体实例赋值的,函数返回值有默认的赋值操作,这里相当于将session类型赋值为结构体实例,不就是接口实现时的操作吗?就是这么简单!
var a AInteface =stu //将结构体实例stu赋给接口变量a a.say() //利用接口变量调用接口内方法
那么我之前为什么会报错呢?我检查了一下代码,发现原来接口没实现,写的结构体方法和接口方法不一致!(害,耗费我大半天劲
//Init一个session,返回session接口变量 func (sm *MemorySessionMgr) SessionInit(sid string) (Session, error) { sm.rwlock.Lock() defer sm.rwlock.Unlock() newsess := &MemorySession{sessionId: sid, data: make(map[string]interface{}, 16)} //返回接口session的变量时,要保证MemorySession这个结构体实现了session中所有接口 return newsess, nil //随后可以利用返回的接口变量,调用接口中的方法-----newsess.Get() }
总结+心得:
1.接口变量为返回值时,函数内返回一个实现了该接口的结构体实例,二者默认进行赋值操作
2.接口主要作用是定义一个统一规范,只有函数名,没有将函数体暴露于外
3.结构体方法要和接口内方法格式一样