本文正在参加金石计划
「前语」
什么是接口
接口是一种标准化的约好或标准,它规则了两个个别之间怎样进行通讯和交互。
假定你要与一个陌生人攀谈,你可能需求恪守一些根本的礼仪标准,比如问候、介绍自己、交换名片等等。这些标准能够协助你和陌生人之间建立信任和合作关系,同时也确保了沟通的顺畅和准确。
在实践编程中,完成一个接口一般需求完成接口界说的一切办法,以确保目标能够被正确运用和调用。这也意味着接口能够被用来强制标准目标的行为,以确保它们契合特定的要求和标准。
接口是一种笼统的工具,由于它并不关心详细的完成细节,而只重视于目标或类应该完成的办法或功用。
假定你正在编写一个程序,需求处理一些动物目标,比如狗、猫、鸟等等。你能够界说一个名为“动物”的接口,它规则了这些目标应该完成哪些办法,比如“吃饭”、“睡觉”、“叫声”等等。这些办法仅仅描绘了动物应该具有的行为,而并不关心这些行为怎样被完成。不同的动物能够根据自己的特点来完成这些办法,比如狗可能会发出“汪汪”声,而猫则可能会发出“喵喵”声。
总的来说,接口是一种有必要恪守的约好与标准,这使得两个个别之间的交互得到了确保,而且其笼统的特性,又是标准具有灵活性而不用恪守死规矩。
怎样声明一个接口
接口类型的界说一般由一组办法签名组成,这些办法签名界说了接口的行为标准。如下:
type Greeter interface{
Greet() string
}
interface{
Add() int
}
这儿咱们声明晰两个接口类型,其间一个名为Greeter
,它里面有一个办法名为Greet
,回来类型为string
的办法签名;别的一个接口它没有类型名,因而它是匿名接口,其内部有一个办法名为Add
,回来值类型为int
的办法签名。
与结构体类似的,接口也答应嵌套,比如如下:
type Adder interface{
Add(int, int) int
}
type Subtractor interface{
Sub(int, int) int
}
type Calculator interface{
Adder
Subtractor
}
在这个比如中,咱们声明晰三个接口,分别是Adder
、Subtractor
与嵌套了前面两者的CalCulator
。Adder
接口中有一个名为Add
,参数类型为两个int
类型,回来值类型为int
类型的办法签名;Subtractor
接口中有一个名为Sub
,参数类型为两个int
类型,回来值类型为int
类型的办法签名。
怎样初始化一个接口变量
完成接口
接口没有被完成,那它是没有含义的,因而运用接口的第一步应该是先完成它:
type Cal struct{}
func (c Cal) Add(i1, i2 int) int {
return i1 + i2
}
func (c Cal) Sub(i1, i2 int) int {
return i1 - i2
}
Go的接口是隐式完成的,只需详细类型的办法集是接口办法的超集,就代表该类型完成了接口。
接口初始化
单纯的声明一个接口变量没有任何含义,接口只有被初始化为详细的类型是才有含义。其初始化条件同样契合「变量」赋值条件的根本逻辑,但是接口的初始化愈加简略,由于只需右值的办法集是左值的超集就能赋值:
-
用结构体赋值
var c Calculator c = Cal{}
-
用接口变量赋值
var c2 Calculator = Cal{} var s Subtractor = c2
接口有什么用
举一个Gin框架路由的比如:
// IRouter defines all router handle interface includes single and group router.
type IRouter interface {
IRoutes
Group(string, ...HandlerFunc) *RouterGroup
}
// IRoutes defines all router handle interface.
type IRoutes interface {
Use(...HandlerFunc) IRoutes
Handle(string, string, ...HandlerFunc) IRoutes
Any(string, ...HandlerFunc) IRoutes
GET(string, ...HandlerFunc) IRoutes
POST(string, ...HandlerFunc) IRoutes
DELETE(string, ...HandlerFunc) IRoutes
PATCH(string, ...HandlerFunc) IRoutes
PUT(string, ...HandlerFunc) IRoutes
OPTIONS(string, ...HandlerFunc) IRoutes
HEAD(string, ...HandlerFunc) IRoutes
Match([]string, string, ...HandlerFunc) IRoutes
StaticFile(string, string) IRoutes
StaticFileFS(string, string, http.FileSystem) IRoutes
Static(string, string) IRoutes
StaticFS(string, http.FileSystem) IRoutes
}
// RouterGroup is used internally to configure router, a RouterGroup is associated with
// a prefix and an array of handlers (middleware).
type RouterGroup struct {
Handlers HandlersChain
basePath string
engine *Engine
root bool
}
api := engine.Group("/api/v1")
api.GET("/tags", tag.List)
以上代码有两个接口,分别是IRouter
和IRoutes
,还有一个结构体RouterGroup
。engine.Group
办法将会创立一个RouterGroup
,并将其赋值给api
。api
的逻辑含义就是作为“/api/v1”
则个组,后面再增加的途径,比如说“api/v1/test”
或许“api/v1/t/a”
之类的一切子途径都在api
这个组别下。而且RouterGroup
通过姓名能够看出它的语义就是一个路由组,而它不光完成了IRouter
,称为一个根途径,而且还完成了IRoutes
,使其能够直接绑定子路由。
通过接口,不光让RouterGroup
具有IRouter
和IRoutes
两种状况,还制定了Router
的处理标准与标准,这就是接口最大的含义——多态性、标准化。