go语言之接口
Go语言中虽然没有传统面向对象语言中类、集成的概念,不过提供了接口的支持,可以使用接口来使用一些面向对象的特性。
在 go 语言中,的接口有下面几个特点:
可以包含0个或多个方法的签名
只定义方法的签名,不包含实现
实现接口不需要显式的声明,只需实现相应方法即可
在 go 中实现接口很简单,不需要显式的声明实现了某个接口,想要实现某个接口,只需要实现接口中的所有方法即可。
package main
import "fmt"
import "math"
type Shaper interface {
Area() float32
Circumference() float32
}
type Rect struct {
Width float32
Height float32
}
type Circle struct {
Radius float32
}
func (r Rect) Area() int {
return r.Width * r.Height
}
func (r Rect) Circumference() int {
return 2 * (r.Width + r.Height)
}
func (c Circle) Area() int {
return math.Pi * c.Radius * c.Radius
}
func (c Circle) Circumference() int {
return math.Pi * 2 * c.Radius
}
func main() {
r := Rect{10, 20}
fmt.Printf("Rect w: %f, d: %f, Area: %f, Circumference: %f", r.Width, r.Height, r.Area(), r.Circumference())
c := Circle{5}
fmt.Printf("Circle r: %f, Area: %f, Circumference: %f", c.Radius, c.Area(), c.Circumference())
}
上面我们定义了一个 Shaper 的接口,其中包含两个方法 Area 和 Circumference,分别用来计算面积和周长。然后我们定义了两个结构体 Rect, Circle 并分别实现了这两个方法。但是上面的程序似乎并没有体现出接口和两个实现类型的关系,下面我们将他们关联起来使用:
func showInfo(s Shaper) {
fmt.Printf("Area: %f, Circumference: %f", s.Area(), s.Circumference())
}
注意,这里方法的参数是一个接口类型的,因此我们可以将实现接口的类型的实例传递进去,像下面这样:
r := Rect{10, 20}
showInfo(r)
c := Circle{5}
showInfo(c)
在上面的 showInfo 中我们传入了接口类型的对象,如果将实现了接口的类型传递进去,那么会将实际类型的其他特性掩盖住,因此通常我们会想要获取其真正的类型, 可以使用下面的方法:
func showInfo(s Shaper) {
switch s.(type) {
case Rect:
fmt.Println("This is Rect")
case Circle:
fmt.Println("This is Circle")
}
fmt.Printf("Area: %f, Circumference: %f\n", s.Area(), s.Circumference())
}
func (a Integer) Less(b Integer) bool{
return a < b
}
func (a *Integer) Add(b Integer){
*a+=b
}
type LessAdder interface{
Less(b Integer) bool
Add(b Integer)
}
赋值的方式如下:
func main(){
var a Integer = 1
var LA LessAdder = a
LA.Less(3)
}
运行报错:
cannot use a (type Integer) as type LessAdder in assignment:
Integer does not implement LessAdder (Add method has pointer receiver)
这个错误的原因是因为Add方法的类型是指针的形式,由类型指针接收的方法必须由对象指针表示和传入。正确的传递方法应该是var LA LessAdder =&a。这样Add方法就能够满足了。那Less方法传递的是非指针,这个时候是否会报错呢?答案是不会的。原因在于Go语言可以根据下面的函数
func (a Integer) Less(b Integer) bool{
return a < b
}
自动生成一个新的Less方法
func (a *Integer) Less(b Integer) bool{
return (*a) < b
}
类型*Integer就既存在Less()方法,也存在Add()方法,满足LessAdder接口。而
从另一方面来说,根据
func (a *Integer) Add(b Integer)
这个函数无法自动生成以下这个成员方法:
func (a Integer) Add(b Integer) {
(&a).Add(b)
}
因为(&a).Add()改变的只是函数参数a,对外部实际要操作的对象并无影响,这不符合用
户的预期。所以,Go语言不会自动为其生成该函数。因此,类型Integer只存在Less()方法,
缺少Add()方法,不满足LessAdder接口.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2017-10-29 python自动化运维六:paramiko
2017-10-29 Django之视图与模板以及在模板中使用bootstrap
2017-10-29 一起来学linux:SSH远程登陆