这是我参与「第三届青训营 -后端场」笔记创作活动的第3篇笔记。有很多语言基础知识在实践中慢慢地就会理解其设计的巧妙。
interface的使用和原理
1.面向接口编程
Go身为现代静态语言,拥有着在动态编程语言中有一种对象推断策略,它更关注的是对象能如何被使用,而不是对象的类型本身,只要有相同的功能则可以被看成同类事物。通俗的讲,只要两个对象拥有公共相同的函数,则两个对象可以视作实现了统一接口,编译器作检测工作。
type One interface {
Eat(s string) error
}
type LittleOne struct {}
func (l *LittleOne) Eat(s string) error {
//......
}
在实现了接口后,就可将本身无法确定的传递参数进行动态传入,不需确定类型,只需实现同一接口,在实际项目开发遇到的一些问题中非常有用。
2.接口动态原理和实践
接口实现动态功能实际上的表现是包含了动态类型和动态值两个部分。
classDiagram
class interface{
动态类型
动动态值()
}
在实际项目开发中,为了降低业务层和数据层的耦合性,想要将数据库连接和使用等封装出去,在面对业务流程中,有时不需要用到事务只需要db,有时需要事务支持时需要用到tx,而封装的时候参数并不可能不按类型随意传入,此时就遇到了db和tx无法根据需要选择传入。此时,接口的使用就非常容易解决了封装时选择传参的问题,db和tx都拥有Exec()等方法的实现,所以可以选择构造一个实现这些方法的接口,将接口作为参数类型,则可实现选择传入。
type dt interface {
Exec(...) ...
//...
}
type db struct {
Exec(...) ...
//...
}
type tx struct {
Exec(...) ...
//...
}
当然Go1.18开始实现了泛型,工具和方法也就多了起来,不过最终这些问题还是显示了更好的使用工具需要更深入了解工具。
3.interface{}
空接口是接口类型的特殊形式,空接口内没有任何方法,任何类型都可以实现空接口,所以很方便的可以使用map[string]interface{}形式保存不同类型值到一个map中,不过有利必有弊,相对于直接用数据对应类型保存数据来说,使用interface{}会稍慢。