一文了解 Go 接口

news/2024/10/31 1:32:31/

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

哈喽大家好,我是陈明勇,今天分享的知识是 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 Afmt.Println(a) // <nil>
}

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

空接口

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

import "fmt"type EmptyInterface interface {
}func main() {var a EmptyInterface = 1var b EmptyInterface = truevar c EmptyInterface = "hello"var d EmptyInterface = 3.14var 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 = 1switch 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 的应用例子。


http://www.ppmy.cn/news/1089.html

相关文章

嵌入式Linux 开发经验:注册一个 misc 设备

前言 之前买过好几本Linux 设备驱动的书&#xff0c;不过对设备驱动一知半解&#xff0c;什么叫设备&#xff0c;什么又叫驱动&#xff1f;最近工作需要&#xff0c;从源码级别深入的研究了一下 Linux 下的设备与驱动的概念&#xff0c;略有所收获 一般提起驱动开发&#xff0…

车载测试好就业?车载测试就业薪资和前景怎么样?

什么是车载智能系统测试&#xff1f; 车载测试&#xff0c;又叫车载智能系统测试&#xff0c;是汽车智能化重要的组成部分&#xff0c;由旧有的车载资通讯系统结合联网汽车技术所演进而来&#xff0c;随着软硬件技术的不断进步&#xff0c; 让车载智能系统拥有强大的运算能力及…

SpringBoot: Controller层的优雅实现

目录1. 实现目标2. 统一状态码3. 统一响应体4. 统一异常5. 统一入参校验6. 统一返回结果7. 统一异常处理8. 验证1. 实现目标 优雅校验接口入参响应体格式统一处理异常统一处理 2. 统一状态码 创建状态码接口&#xff0c;所有状态码必须实现这个接口&#xff0c;统一标准 pa…

【YOLO系列改进NO.45】首发最新特征融合技术RepGFPN(DAMO-YOLO)

文章目录前言一、解决问题二、基本原理三、​添加方法四、总结前言 作为当前先进的深度学习目标检测算法YOLOv7&#xff0c;已经集合了大量的trick&#xff0c;但是还是有提高和改进的空间&#xff0c;针对具体应用场景下的检测难点&#xff0c;可以不同的改进方法。此后的系列…

【Python百日进阶-数据分析】Day121 - Plotly Figure参数: 散点图(三)marker 标记

文章目录marker 标记marker 标记 代码&#xff1a; fig.update_traces(markerdict(…), selectordict(type‘scatter’)) 类型&#xff1a;包含下面列出的一个或多个键的字典。 autocolorscale 自动色标 代码&#xff1a; fig.update_traces(marker_autocolorscale, selectord…

Nexus私服(三)

(一) maven中snapshots和releases snapshots快照在maven指的是开发阶段的版本,会频繁的更新,常指在开发测试阶段,一般在pom的版本中声明1.0-SNAPSHOTsnapshots快照的引入是为了解决开发阶段依赖的问题。当我们的版本号中不显示声明SNAPSHOT,maven会默认你的是releases稳定版本。…

Yolo算法检测之Anchor Boxes原理详解

刚开始yolo系列的目标检测算法&#xff0c;在一个网格中只能检测一个对象&#xff0c;但是我们在实验中发现&#xff0c;一个网格中很多时候存在不仅一个目标&#xff0c;可能存在多个目标&#xff0c;类似如下图所示&#xff0c;下面中间的网格中就存在人和车辆两个目标的中心…

十一、【React-Router6】Hooks 汇总

文章目录 1.useRoutes() 2. useNavigate() 3. useParams() 4. useSearchParams() 5. useLocation() 6. useMatch() 7. useInRouterContext() 8. useNavigationType() 9. useOutlet() 10. useResolvedPath() 1、useRoutes() 根据路由表&#xff0c;动态创建 <Routes> 和…