一文了解 Go 接口

简介: 我是陈明勇,本文分享的知识是 Go 接口。如果本文对你有帮助,不妨点个赞,如果你是 Go 语言初学者,不妨点个关注,一起成长一起进步,如果本文有错误的地方,欢迎指出!

耐心和持久胜过激烈和狂热。

我是陈明勇,本文分享的知识是 Go 接口。如果本文对你有帮助,不妨点个赞,如果你是 Go 语言初学者,不妨点个关注,一起成长一起进步,如果本文有错误的地方,欢迎指出!

接口

Go 语言中,接口是一种抽象的类型,是一组方法的集合。接口存在的目的是定义规范,而规范的细节由其他对象去实现。我们来看一个例子:

import "fmt"
type Person struct {
    Name string
}
func main() {
    person := Person{Name: "cmy"}
    fmt.Println(person) // {cmy}
}
复制代码

上述代码定义了结构体 Personmain 函数创建了此结构体的变量 person,然后通过 fmt 包里的 Println 函数打印这个结构体,打印结果为 {cmy}。在此基础上,我们改造一下代码:

import "fmt"
type Person struct {
    Name string
}
func (p Person) String() string {
    return fmt.Sprintf("name: %s", p.Name)
}
func main() {
    person := Person{Name: "cmy"}
    fmt.Println(person) // name: cmy
}
复制代码

新改造的代码里为结构体 Person 添加一个结构体方法 String() string,方法的返回结果是对 name 进行格式化,我们再打印一下结构体,观察结果发现是 String() 方法返回的值,而不是  {cmy}。 为什么是这样呢?这是因为 fmt.Println(T) 函数的实现细节里,会对结构体进行判断,如果结构体实现了 Stringer 接口,则会直接打印 String() 方法的返回值。以下是 Stringer 接口的代码:

type Stringer interface {
    String() string
}
复制代码

结构体实现了这个接口,也就意味着遵守这个接口所定义的规范,fmt.Println(T) 函数发现结构体有这个规范,因此就会根据规范来打印信息。基于 Stringer 接口,我们来看看接口的语法格式:

type XXX interface {
    // methods
}
复制代码
  • 1、type
    接口的声明,必须以 type 关键字开头。
  • 2、接口名
    推荐驼峰式命名法,首字母大写的方法名可以在包外访问,小写的只能在包内访问。
  • 3、interface
    接口的标识。
  • 4、接口体
    大括号里面声明规范,也就是声明方法,方法必须具有名字。

接口的实现

  • Go 语言里,接口的实现不是基于接口,而是基于方法。如果一个自定义类型拥有了某个接口的所有方法,那么这个自定义类型就实现这个接口。接口的实现在上述的例子中有所体现,Person 结构体定义了 String() string 方法,拥有了 Stringer 接口的所有方法,因此实现了 Stringer 接口。
  • 一个自定义类型可以实现多个接口
type A interface {
        a()
}
type B interface {
        b()
}
type Person struct {
        Name string
}
func (p Person) a() {
}
func (p Person) b() {
}
复制代码
  • A 接口声明了 a 方法, B 接口声明了 b 方法,Person 结构体定义了 ab 两个方法,因此 Person 结构体实现了 AB 两个接口。

接口类型变量

一旦接口被定义,它就可以用于声明变量。

import "fmt"
type A interface {
}
func main() {
    var a A
    fmt.Println(a) // <nil>
}
复制代码

如果只声明接口变量,不初始化,变量的值默认为 nil,因为接口类型实际上是一个指针。若为接口赋初值,需要选择一个合法的值,即被赋值的基类必须实现这个接口。

空接口

Go 语言里面可以认为所有类型实现了空接口,因为空接口没有任何的方法。

import "fmt"
type EmptyInterface interface {
}
func main() {
    var a EmptyInterface = 1
    var b EmptyInterface = true
    var c EmptyInterface = "hello"
    var d EmptyInterface = 3.14
    var e EmptyInterface = 'c'
    fmt.Println(a, b, c, d, e) // 1 true hello 3.14 99
}
复制代码

所有类型都实现空接口,因此空接口变量可以被赋初值为任意类型的值或变量。

类型断言

Go 语言支持类型断言操作,通过这个操作,可以还原接口变量的右值(被赋的初值)。类型断言的语法形式通常为:

v, ok := a.(T)
复制代码

如果断言成功,那么 v 的值为接口变量的值,ok 的值为 true;如果断言失败,v 的值为 T 类型的零值,ok 的值为 false

类型断言变种 type switch

通过 type switch 的方式,可以判断接口变量属于哪种动态类型。

import "fmt"
type EmptyInterface interface {
}
func main() {
    var a EmptyInterface = 1
    switch a.(type) {
    case string:
  fmt.Println("a 的右值类型为 string")
    case int:
  fmt.Println("a 的右值类型为 int")
    case bool:
  fmt.Println("a 的右值类型为 bool")
    case float64:
  fmt.Println("a 的右值类型为 float64")
    }
}
复制代码

小结

本文先是对接口的定义进行介绍,然后通过一个例子,了解了接口其中的一个应用场景和引出接口的语法格式以及实现的方法,然后介绍了空接口的特点和类型断言,最后介绍了变种的类型断言 type switch 的应用例子。

目录
相关文章
|
17天前
|
设计模式 存储 监控
《Go 简易速速上手小册》第4章:接口与抽象(2024 最新版)(上)
《Go 简易速速上手小册》第4章:接口与抽象(2024 最新版)
41 1
|
1月前
|
自然语言处理 Go 索引
Go语言学习8-接口类型
【4月更文挑战第1天】本篇 Huazie 向大家介绍 Go 语言中的接口类型
21 2
Go语言学习8-接口类型
|
2月前
|
Go
|
4月前
|
存储 设计模式 Cloud Native
云原生系列Go语言篇-类型、方法和接口 Part 1
通过前面章节的学习,我们知道Go是一种静态类型语言,包含有内置类型和用户定义类型。和大部分现代编程语言一样,Go允许我们对类型关联方法。它也具备类型抽象,可以编写没有显式实现的方法。
51 0
|
7月前
|
JSON Go 数据格式
Go 语言怎么处理三方接口返回数据?
Go 语言怎么处理三方接口返回数据?
70 0
|
6天前
|
程序员 Go
|
1月前
|
存储 安全 Go
掌握Go语言:Go语言类型转换,无缝处理数据类型、接口和自定义类型的转换细节解析(29)
掌握Go语言:Go语言类型转换,无缝处理数据类型、接口和自定义类型的转换细节解析(29)
|
7天前
|
存储 Go 开发者
【Go语言专栏】深入探索Go语言的接口与多态
【4月更文挑战第30天】本文探讨了Go语言中的接口和多态性。接口是方法集合的抽象类型,允许不同类型的值实现相同的方法,实现多态。接口定义不包含实现,仅包含方法签名。类型实现接口是隐式的,只要实现了接口所需的方法。接口用于编写与具体类型无关的通用代码。通过接口,不同类型的对象可以响应相同消息,展现多态性。此外,接口可以嵌入以继承其他接口,类型断言则用于访问接口内部的具体类型。空接口可存储任何类型值。理解并掌握接口有助于编写更灵活、模块化的Go代码。
|
17天前
|
存储 设计模式 Go
《Go 简易速速上手小册》第4章:接口与抽象(2024 最新版)(下)
《Go 简易速速上手小册》第4章:接口与抽象(2024 最新版)
26 1
|
2月前
|
安全 Go
接口在Go语言中的实现与应用
【2月更文挑战第19天】接口是Go语言中一种重要的抽象机制,它定义了一组方法的集合,而不关注具体的实现。本文将深入探讨Go语言中接口的实现方式、接口的应用场景以及接口在Go语言设计中的优势,帮助读者更好地理解和应用接口。