教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 Go语言中的接口

Go语言中的接口

发布时间:2021-05-16   编辑:jiaochengji.com
教程集为您提供Go语言中的接口等资源,欢迎您收藏本站,我们将为您提供最新的Go语言中的接口资源

下面的内容抄了好多本书,我也不知道有哪些了,大概有《Go语言核心编程》---许士伟,《Go并发编程实战(第二版)》--郝林

侵入式”的主要表现在于实现类需要明确声明自己实现了某个接口。Go语言中的接口是非侵入式的,体现为:在Go语言中,一个类只需要实现了接口包含的所有函数,我们就说这个类实现了该接口。(方法多的接口或者对象可以赋值给方法少的接口或者对象)。接口类型是一种抽象的类型,它不会暴露出它所代表的对象的内部值的结构和这个对象支持的基础操作的集合;它们只会展示出它们自己的方法。也就是说当你有看到一个接口类型的值时,你不知道它是什么,唯一知道的就是可以通过它的方法来做什么

GO语言中,接口类型具体描述了一系列方法的集合,一个实现了  接口所包含的方法    的具体类型是这个接口类型的实例。

一个类型如果拥有一个接口需要的所有方法,那么这个类型就实现了这个接口

接口的动态类型和静态类型

接口的动态类型:接口绑定的具体实例的类型称为接口的动态类型。接口可以绑定不同类型的实例,所以接口的动态类型是随着其绑定的不同类型示例代码而发生变化的。

接口的静态类型:接口被定义的时候,其类型就已经被确定,这个类型叫做接口的静态类型。接口的静态类型在其定义的时候就被确定。静态类型的本质特征就是接口的方法签名集合。两个接口如果方法签名集合相同(方法的顺序可以不同),则这两个接口在语义上完全等价,它们之间不需要强制类型转换就可以相互赋值。原因在于Go编译检验接口是否能赋值,是比较二者的方法集而不是看具体接口类型名

 

接口值

概念上讲一个接口的值,接口值,由两个部分组成,一个具体的类型和那个类型的值。它们被称为接口的动态类型和动态值。对于像 Go 语言这种静态类型的语言,类型是编译期的概念;因此一个类型不是一个值。在我们的概念模型中,一些提供每个类型信息的值被称为类型描述符,比如类型的名称和方法。在一个接口值中,类型部分代表与之相关类型的描述符。

在 Go 语言中,变量总是被一个定义明确的值初始化,即使接口类型也不例外。对于一个接口的零值就是它的类型和值的部分都是 nil。

接口值可以使用==和!=来进行比较。两个接口值相等仅当它们都是nil值或者它们的动态类型相同且动态值也根据这个动态类型的==操作相等。

因为接口值是可比较的,所以它们可以用在 map 的键或者作为 switch 语句的操作数。然而,如果两个接口值的动态类型相同,但是这个动态类型是不可比较的(比如切片),将它们进行比较就会失败并且 panic。

考虑到这点,接口类型是非常与众不同的。其它类型要么是安全的可比较类型(如基本类型和指针)要么是完全不可比较的类型(如切片,映射类型,和函数)但是在比较接口值或者包含了接口值的聚合类型时,我们必须要意识到潜在的 panic。同样的风险也存在于使用接口作为 map 的键或者 switch 的操作数。只能比较你非常确定它们的动态值是可比较类型的接口值。

一个包含nil指针的接口不是nil接口。因为:一个不包含任何值的nil接口值和一个刚好包含nil指针的接口值是不同的。

接口赋值

接口赋值在Go语言中分为如下两种情况:

  将对象实例赋值给接口;

  将一个接口赋值给另一个接口

先讨论将某种类型的对象实例赋值给接口,这要求该对象实例实现了接口要求的所有方法

再来讨论另一种情形:将一个接口赋值给另一个接口。在Go语言中,只要两个接口拥有相同的方法列表(次序不同不要紧),那么它们就是等同的,可以相互赋值接口赋值并不要求两个接口必须等价。如果接口A的方法列表是接口B的方法列表的子集,那么接口B可以赋值给接口A(子集可以赋值给父集)

 

接口查询

接口查询是否成功,要在运行期才能够确定。它不像接口赋值,编译器只需要通过静态类型检查即可判断赋值是否可行。Go语言中,你可以询问接口它指向的对象是否是某个类型,比如:

var file1 Writer = ...

if file6, ok := file1.(*File); ok {

...

}

这个 if 语句判断 file1 接口指向的对象实例是否是 *File 类型,如果是则执行特定代码。查询接口所指向的对象是否为某个类型的这种用法可以认为只是接口查询的一个特例。接口是对一组类型的公共特性的抽象

类型查询

在Go语言中,还可以更加直截了当地询问接口指向的对象实例的类型,如:

var v1 interface{} = ...

switch v := v1.(type) {

case int: // 现在v的类型是int

case string: // 现在v的类型是string

...

}

Any类型

由于GO语言中任何对象实例都满足空接口interface{ },所以interface看起来像是可以指向任何对象的Any类型。

类型断言

类型断言是一个使用在接口值上的操作。语法上看起来像 x.(T)被称为断言类型,这里 x 表示一个接口的类型T 表示一个类型。一个类型断言检查它操作对象的动态类型是否和断言的类型匹配

这里有两种可能。第一种,如果断言的类型 T 是一个具体类型,然后类型断言检查 x 的动态类型是否和 T 相同。如果这个检查成功了,类型断言的结果是 x 的动态值当然它的类型是 T。换句话说,具体类型的类型断言从它的操作对象中获得具体的值。如果检

查失败,接下来这个操作会抛出 panic

第二种,如果相反断言的类型 T 是一个接口类型,然后类型断言检查是否 x 的动态类型满足 T。如果这个检查成功了,动态值没有获取到;这个结果仍然是一个有相同类型和值部分的接口值,但是结果有类型 T。换句话说,对一个接口类型的类型断言改变了类

型的表述方式,改变了可以获取的方法集合(通常更大),但是它保护了接口值内部的

动态类型和值的部分

 

到此这篇关于“Go语言中的接口”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
想系统学习GO语言(Golang
go run main.go 参数_Go语言入门:Hello world
Go语言学习3----Go语言特色
go 获取函数地址_Go语言基础--接口浅析
Go 语言到底适合干什么?
关于golang面向接口
Go语言空接口类型(interface{})
go语言学习-接口赋值的两种类型
初识 go 语言:方法,接口及并发
Go语言发展历史、核心、特性及学习路线

[关闭]
~ ~