go编程中接口(interface)用法

1、编程中多态的概念

如果熟悉C++编程,就会知道C++中可以通过虚函数来实现多态 ,Java等面向对象的语言也有类似的特性。那么是多态呢?

多态是面向对象编程中的一个基本概念,允许不同的类通过相同的接口实现不同的功能 。简而言之,多态使得一个接口可以有多个实现,从而可以处理不同类型的对象,而无需知道它们的具体类型。

在 Go 语言中,多态主要通过接口实现。接口定义了一组方法,而不同的类型可以实现这些方法,从而实现接口。这样,可以使用接口类型的变量来引用实现了该接口的不同类型的对象。

--from chatGPT

多态是面向对象编程的一个概念,其核心相同的接口,具有不同的实现,从而达到调用相同的接口实现不同的功能。

(go语言由于没有类这个概念,所以严格来讲,go中接口不能算是多态,但是核心思想是一样的。)

2、interface概念

前面已经提到,go interface其实就是与多态相关的一个概念。

Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。

接口可以让我们将不同的类型绑定到一组公共的方法上,从而实现多态和灵活的设计。

Go 语言中的接口是隐式实现的,也就是说,如果一个类型实现了一个接口定义的所有方法,那么它就自动地实现了该接口。因此,我们可以通过将接口作为参数来实现对不同类型的调用,从而实现多态。

-- from 菜鸟教程

3、用法举例

3.1 最简单的demo

为了让初学者有一个最直观的认识,先看一个最简单的demo:

Go 复制代码
package main

import (
    "fmt"
)
// 定义一个接口,里面包含一个area方法
// 这里起始也可以包含多个方法
type Shape interface {
    area() float64
}
// 定义长方形结构体
type Rectangle struct {
    width  float64
    height float64
}
// 实现长方形结构体的area方法
func (r Rectangle) area() float64 {
    return r.width * r.height
}
// 定义圆结构体
type Circle struct {
    radius float64
}
// 实现圆的area方法
func (c Circle) area() float64 {
    return 3.14 * c.radius * c.radius
}

func main() {
    // 定义一个接口变量
    var shape Shape

    shape = Rectangle{width: 10, height: 5}
    fmt.Printf("矩形面积: %f\n", shape.area())

    shape =  Circle{radius: 3}
    fmt.Printf("圆形面积: %f\n",  shape.area())

}

输出结果如下:

矩形面积: 50.000000

圆形面积: 28.260000

从上面可以看到,同一个接口方法area,由于不同的结构体具有不同的实现,从而不同的结构体对象调用同一个方法时,表现出各自的功能。

3.2 比较贴近实际业务案例

在处理实际业务时,我们可能会根据接收到不同的消息,从而自动调用相关的方法进行处理。为此,我们需要先将不同的接口实现方法进行注册,然后根据不同的消息进行处理。

Go 复制代码
package main

import "fmt"

type Shape interface {
    area() float64
}

type Rectangle struct {
    width  float64
    height float64
}

func (r Rectangle) area() float64 {
    return r.width * r.height
}

type Circle struct {
    radius float64
}

func (c Circle) area() float64 {
    return 3.14 * c.radius * c.radius
}

type Registry struct {
    shape map[int]Shape
}

// 创建一个新的注册器
func NewRegistry() *Registry {
    return &Registry{shape: make(map[int]Shape)}
}

// 注册处理函数
func (r *Registry) Register(id int, shape Shape) {
    r.shape[id] = shape
}

func (r *Registry) Get(id int) Shape {
    return r.shape[id]
}
// 定义不同的消息ID
const (
	MSG_UNKNOW = 0
	MSG_RECTANGLE = 1
	MSG_CIRCLE = 2
)
func main() {
    //var s Shape
	registry := NewRegistry()
	// 注册不同的方法,将结构体类型与消息ID绑定,从而根据不同的消息ID调用不同的方法
	registry.Register(MSG_CIRCLE,  Circle{radius: 3})
	registry.Register(MSG_RECTANGLE, Rectangle{width: 10, height: 5})
	var msgId int
	// 假如收到的消息id为MSG_RECTANGLE
	msgId = MSG_RECTANGLE
	r := registry.Get(msgId)
    fmt.Printf("面积: %f\n", r.area())
}

参考资料:

【1】Go 语言接口 | 菜鸟教程

相关推荐
紧跟先前的步伐1 天前
Go AI Agent 实战 22|完善 Agent 执行循环:从工具调用到最终回答
人工智能·ai·golang
后台模板学习1 天前
Go Web开发中任务调度框架的源码解析与高可用实现方案
开发语言·后端·golang
FungLeo1 天前
成为全栈·Go 后端篇·分类树与标签关系:目录变更为何需要协调
golang·go·gorm·数据库事务·分类树·成为全栈
fly-iot1 天前
【FDE知识库】(1):AI 编程时代开发语言选型分析,云使用go,企业用java,算法python,底层c
开发语言·人工智能·golang
FungLeo1 天前
成为全栈·Go 后端篇·文章查询与展示投影:安全分页、排序和软删除
golang·go·gorm·分页查询·成为全栈·sql安全
紧跟先前的步伐1 天前
Go AI Agent 实战 24|工具系统工程化收尾与阶段验收
人工智能·ai·golang·1024程序员节
日日大王学编程1 天前
#Feed 流项目复盘:Redis 时间线缓存与 Outbox 消息可靠性设计
golang·1024程序员节
Bshaya_2 天前
C++多态详解:运行时多态、虚函数重写与析构函数重写规则
多态·析构函数·虚函数·重写·静态多态
北冥you鱼2 天前
Go 语言 CRUD 实战:从接口设计到真实业务场景
开发语言·后端·golang
利威尔xu2 天前
Go IM 源码实战(11):token 只是个 HASH,多端互踢的顺序错了就踢错人
后端·微服务·面试·架构·golang