广告位联系
返回顶部
分享到

Go语言中的接口类型介绍

Golang 来源:互联网 作者:佚名 发布时间:2024-08-17 22:13:51 人浏览
摘要

接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现规范的细节。 1.接口类型 1.1 接口类型的说明 Go语言中接口(interface)是一种抽象的类型。 接口(interfa

接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现规范的细节。

1.接口类型

1.1 接口类型的说明

Go语言中 接口(interface) 是一种抽象的类型。

接口(interface) 是一组 方法 的集合,是 duck-type programming(鸭子类型) 的一种体现,接口所做的事情就像是定义一个协议(规则),只要一台机器有洗衣和甩干的功能,就称之为洗衣机,不关心属性(数据),只关心行为(方法)。

1.2 接口类型的定义

Go语言提倡面向接口编程。

接口是一个或多个方法签名的集合。
任何类型的方法集中只要拥有该接口'对应的全部方法'签名。
就表示它 "实现" 了该接口,无须在该类型上显式声明实现了哪个接口。
这称为Structural Typing。
所谓对应方法,是指有相同名称、参数列表 (不包括参数名) 以及返回值。
当然,该类型还可以有其他方法。

接口只有方法声明,没有实现,没有数据字段。
接口可以匿名嵌入其他接口,或嵌入到结构中。
对象赋值给接口时,会发生拷贝,而接口内部存储的是指向这个复制品的指针,既无法修改复制品的状态,也无法获取指针。
只有当接口存储的类型和对象都为nil时,接口才等于nil。
接口调用不会做receiver的自动转换。
接口同样支持匿名字段方法。
接口也可实现类似OOP中的多态。
空接口可以作为任何类型数据的容器。
一个类型可实现多个接口。
接口命名习惯以 er 结尾。

每个接口由数个方法组成,接口的定义格式如下:

1

2

3

4

5

type 接口类型名 interface{

    方法名1( 参数列表1 ) 返回值列表1

    方法名2( 参数列表2 ) 返回值列表2

    …

}

其中:

1.接口名:使用type将接口定义为自定义的类型名。Go语言的接口在命名时,一般会在单词后面添加er,如有写操作的接口叫Writer,有字符串功能的接口叫Stringer等。接口名最好要能突出该接口的类型含义。
2.方法名:当方法名首字母是大写且这个接口类型名首字母也是大写时,这个方法可以被接口所在的包(package)之外的代码访问。
3.参数列表、返回值列表:参数列表和返回值列表中的参数变量名可以省略。

举个例子:

1

2

3

type writer interface{

    Write([]byte) error

}

这里定义了一个 writer 的 接口(interface),能够看到的就只是这个接口定义了一个 Write 方法,具体实现什么功能也不可知。

1.3 实现接口的条件

一个对象只要全部实现了接口中的方法,那么就实现了这个接口。换句话说,接口就是一个需要实现的方法列表。

举个例子,这里我们定义一个 Phone 对象

1

2

3

4

type Phone interface {

    Call()

    SendMessage()

}

定义 OPPO 和 HUAWEI 两个结构体:

1

2

3

4

5

6

7

8

9

type OPPO struct {

    Name  string

    Price float64

}

 

type HUAWEI struct {

    Name  string

    Price float64

}

Phone 接口中有两个方法 Call 和 SendMessage 方法,因此需要给 OPPO 和 HUAWEI 实现 Call 和 SendMessage 方法就实现了 Phone 接口。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

func (oppo OPPO) Call() {

    fmt.Printf("%s 有打电话的功能 \n", oppo.Name)

}

 

func (oppo OPPO) SendMessage() {

    fmt.Printf("%s 有发短信的功能 \n", oppo.Name)

}

 

func (huawei HUAWEI) Call() {

    fmt.Printf("%s 有打电话的功能 \n", huawei.Name)

}

 

func (huawei HUAWEI) SendMessage() {

    fmt.Printf("%s 有发短信的功能 \n", huawei.Name)

}

接口的实现就是这样,只要实现了接口中的所有方法,就实现了这个接口。

1.4 接口变量类型

接口类型变量能够存储所有实现了该接口的实例。如上 1.3 实现接口的条件 举例所示,Phone 类型的变量能够存储 HUAWEI 和 OPPO 类型的变量。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

func interfaceVariable() {

    // 声明一个Phone 类型的变量x

    var x GoInterface.Phone

    // 实例化一个OPPO

    findx6 := GoInterface.OPPO{

        Name:  "Find X6",

        Price: 5999,

    }

    // 实例化一个HUAWEI

    p30 := GoInterface.HUAWEI{

        Name:  "HUAWEI P30",

        Price: 3999,

    }

    // 可以把OPPO实例直接赋值给x

    x = findx6

    x.Call()

    // 可以把HUAWEI实例直接赋值给x

    x = p30

    x.Call()

}

2. 类型与接口之间的关系

2.1 一个类型实现多个接口

一个类型可以同时实现多个接口,而接口间彼此独立,不知道对方的实现。 例如,OPPO 手机可以打电话,也可以发短信。我们就分别定义 Caller 接口和 Message 接口,如下:

1

2

3

4

5

6

7

type Caller interface {

    Call()

}

 

type Message interface {

    SendMessage()

}

OPPO 既可以实现 Caller 接口,也可以实现 Message 接口。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

type OPPO struct {

    Name  string

    Price float64

}

 

// 实现Caller接口

func (oppo OPPO) Call() {

    fmt.Printf("%s支持打电话功能\n", oppo.name)

}

 

// 实现Message接口

func (oppo OPPO) SendMessage() {

    fmt.Printf("%s支持发短信功能\n", oppo.name)

}

 

func main() {

    var x Caller

    var y Message

 

    var a = OPPO{Name: "Find X6", Price:5999,}

    x = a

    y = a

    x.Call()

    y.SendMessage()

}

2.2 多个类型实现同一接口

Go语言中不同的类型还可以实现同一接口,首先我们定义一个 Caller 接口,它要求必须由一个 Call 方法。

1

2

3

type Caller interface {

    Call()

}

例如,HUAWEI 手机可以打电话,OPPO 也可以打电话。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

type OPPO struct {

    Name  string

    Price float64

}

 

type HUAWEI struct {

    Name  string

    Price float64

}

 

// OPPO 类型实现Caller接口

func (oppo OPPO) Call() {

    fmt.Printf("%s 有打电话的功能 \n", oppo.Name)

}

 

// HUAWEI 类型实现Caller接口

func (huawei HUAWEI) Call() {

    fmt.Printf("%s 有打电话的功能 \n", huawei.Name)

}

并且一个接口的方法,不一定需要由一个类型完全实现,接口的方法可以通过在类型中嵌入其他类型或者结构体来实现。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

// Phone

type Phone interface {

    NFC()

    Call()

}

 

// NFC模块

type NFCER struct{}

 

// 实现Phone接口的NFC()方法

func (nfc NFC) NFC() {

    fmt.Println("NFC刷卡")

}

 

// OPPO手机

type OPPO struct {

    NFCER //嵌入NFC模块

}

 

// 实现Phone接口的Call()方法

func (oppo OPPO) Call() {

    fmt.Println("OPPO手机支持打电话功能")

}

3.空接口

3.1 空接口的定义

空接口是指没有定义任何方法的接口。因此任何类型都实现了空接口。

空接口类型的变量可以存储任意类型的变量。

1

2

3

4

5

6

7

8

9

10

11

12

13

func emptyInterface() {

    // 定义一个空接口x

    var x interface{}

    s := "euansu.cn"

    x = s

    fmt.Printf("type:%T value:%v\n", x, x)

    i := 100

    x = i

    fmt.Printf("type:%T value:%v\n", x, x)

    b := true

    x = b

    fmt.Printf("type:%T value:%v\n", x, x)

}

3.2 空接口的应用

空接口可以实现接口任意类型的函数参数。

1

2

3

4

// 空接口作为函数参数

func funcMethod(a interface{}) {

    fmt.Printf("type:%T value:%v\n", a, a)

}

空接口可以作为 map 的值。

1

2

3

4

5

6

// 空接口作为map值

var studentInfo = make(map[string]interface{})

studentInfo["name"] = "李白"

studentInfo["age"] = 18

studentInfo["married"] = false

fmt.Println(studentInfo)


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • Go语言等待组sync.WaitGrou的使用
    Go语言中除了可以使用通道(channel)和互斥锁进行两个并发程序间的同步外,还可以使用等待组进行多个任务的同步,等待组可以保证在并
  • Go语言中的接口类型介绍
    接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现规范的细节。 1.接口类型 1.1 接口类型的说明 Go语言中
  • Go语言占位符的使用介绍
    Golang的字符串占位符在fmt包的各种打印函数中使用,如fmt.Printf、fmt.Sprintf。 变量值与类型的打印 %v: 打印变量的值 %v会根据变量的类型选择
  • 基于Golang实现Kubernetes边车模式

    基于Golang实现Kubernetes边车模式
    在这篇文章中,我们会介绍 Sidecar 模式,并创建两个基于 Go 的容器化微服务,然后部署到 Kubernetes 上。 什么是 Sidecar 模式? Sidecar 模式是一
  • 使用Go语言实现基于泛型的Jaccard相似度算法

    使用Go语言实现基于泛型的Jaccard相似度算法
    基本原理 跳表: jaccard相似度: jaccard相似度的代码实现: 时间复杂度分析: 快速jaccard算法: 代码实现,这个要求两个集合都是有序的:
  • go-zero自定义中间件的几种方式
    1.通过 api 文件生成并填入具体逻辑 定义 api 首先你需要在 api 文件中定义你需要的路由位置和中间件的名字: 1 2 3 4 5 6 7 8 9 // test for ping @
  • Go中gin框架的*gin.Context参数常见实用方法
    梗概: *gin.Context是处理HTTP请求的核心。ctx代表context(上下文),它包含了处理请求所需的所有信息和方法,例如请求数据、响应构建器、
  • Python实现图像添加水印的方法
    在日常图像处理中,为图片添加水印是一项常见任务。有多种方法和工具可供选择,而今天我们将专注于使用Python语言结合PIL库批量添加水
  • go的defer和return的执行顺序介绍
    go的defer和return的执行顺序 go的defer和return是golang中的两个关键字,return用于返回函数的返回值,也可以参与一定的流程控制,比如下面代码
  • 使用go语言实现Redis持久化的代码
    redis是一个内存数据库,如果你把进程杀掉,那么里面存储的数据都会消失,那么这篇文章就是来解决redis持久化的问题 我们在redis.conf文件
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计