没有合适的资源?快使用搜索试试~ 我知道了~
Go语言基础、进阶、提高课程--第八节 深入理解interface1
需积分: 0 0 下载量 91 浏览量
2022-08-03
14:41:31
上传
评论
收藏 937KB PDF 举报
温馨提示
试读
14页
答案是否定的,Go 语言引入了一种新类型—Interface,它在效果上实现了类似于 C++的“多态”概念,虽然与 C++的多态在语法上并非完全对等,但至少在最
资源详情
资源评论
资源推荐
成都字节跳动教育咨询有限公司(www.ByteEdu.Com)
课程安排,请关注微信公众平台或者官方微博
编程语言: Golang 与 html5
编程工具: Goland 和 HBuilder
预计平均一周左右更新一或二节课程
授人以鱼,不如授人以渔业。
大家好,
欢迎来到 字节教育 课程的学习
社区论坛网址:www.Golang.Ltd
技术交流群 : 221273219
微信公众号 :Golang 语言社区
微信服务号 :Golang 技术社区
第一季 Go 语言基础、进阶、提高课程
第二十二节 深入理解 interface
Go 不是一种典型的面向对象编程的语言,它在语法上不支持类和继承的概念。
没有继承是否就无法拥有多态行为了呢?答案是否定的,Go 语言引入了一种新类型—Interface,它在效果上实现
了类似于 C++的“多态”概念,虽然与 C++的多态在语法上并非完全对等,但至少在最终实现的效果上,它有多态
的影子。那么,Go 的 Interface 类型到底是什么呢?怎么使用呢?这正是本节说明的问题。
1、Method(s) in Go
在说明 Interface 类型前,不得不先用 Go 的 method(s)概念来热身,因为 Go 语言的 interface 与 method(s)
这两个语法有非常紧密的联系。虽然 Go 语言没有类的概念,但它支持的数据类型可以定义对应的 method(s)。本
质上说,所谓的 method(s)其实就是函数,只不过与普通函数相比,这类函数是作用在某个数据类型上的,所以
在函数签名中,会有个 receiver 来表明当前定义的函数会作用在该 receiver 上。关于 methods 的精确语法规范,
可以参考 language specification 或 Effective Go 中的说明,这里略过。注意:Go 语言支持的除 Interface 类
型外的任何其它数据类型都可以定义其 method(而并非只有struct才支持method),只不过实际项目中,method(s)
多定义在 struct 上而已。在 struct 类型上定义 method(s)的语法特性与 C++中的 struct 支持的语法非常类似(c++
中的 struct 定义了数据,此外也支持定义数据的操作方法),从这一点来看,我们可以把 Go 中的 struct 看作是
成都字节跳动教育咨询有限公司(www.ByteEdu.Com)
不支持继承行为的轻量级的“类”。
2、 what is Interface tyce in Go?
GoLang 官网 language specification 文档对 interface type 的概念说明如下:
An interface type specifies a method set called its interface. A variable of interface type can store a va
lue of any type with a method set that is any superset of the interface. Such a type is said to imple
ment the interface. The value of an uninitialized variable of interface type is nil.
说实话,这段说明对新手来说比较晦涩,这正是本节试图解释清楚的地方。
从语法上看,Interface 定义了一个或一组 method(s),这些 method(s)只有函数签名,没有具体的实现代码(有
没有联想起 C++中的虚函数?)。若某个数据类型实现了 Interface 中定义的那些被称为"methods"的函数,则称
这些数据类型实现(implement)了 interface。举个例子来说明。
package main
import (
"fmt"
"math"
)
type Abser interface {
Abs() float64
}
type MyFloat float64
func (f MyFloat) Abs() float64 {
if f < 0 {
return float64(-f)
}
return float64(f)
}
func main() {
var a Abser
f := MyFloat(-math.Sqrt2)
a = f // a MyFloat implements Abser
fmt.Println(a.Abs())
}
上面的代码中,第 8-10 行是通过 type 语法声明了一个名为 Abser 的 interface 类型(Go 中约定的 interface
成都字节跳动教育咨询有限公司(www.ByteEdu.Com)
类型名通常取其内部声明的 method 名的 er 形式)。而第 12-19 行通过 type 语法声明了 MyFloat 类型且为该类型
定义了名为 Abs()的 method。根据上面的解释,Abs()是 interface 类型 Abser 定义的方法,而 MyFloat 实现了该
方法,所以,MyFloat 实现了 Abser 接口。
Interface 类型的更通用定义可归纳如下:
type Namer interface {
Method1(param_list) return_type
Method2(param_list) return_type
...
}
上面的示例用 type 语法声明了一个名为 Namer 的 interface 类型(但 Namer 不是个具体的变量,此时内存
中还没有它对应的对象)。interface 类型是可以定义变量的,也即 interface type can have values,例如:
var ai Namer
此时,定义了一个变量名为 ai 的 Namer 类型变量,在 Go 的底层实现中,ai 本质上是个指针,其内存布局
如下(内存布局图引用自<The Way to Go - A Thorough Introduction to the Go Programming Language>一
书第 11.1 节):
它的 method table ptr 是不是与 C++中类的虚函数表非常类似?而这正是 interface 类型的变量具有多态特性的
关键:
ai 共占 2 个机器字,1 个为 receiver 字段,1 个为 method table ptr 字段。ai 可以被赋值为任何变量,只要这个
变量实现了 interface 定义的 method(s) set,赋值后,ai 的 receiver 字段用来 hold 那个变量或变量副本的地址(若
变量类型小于等于 1 个机器字大小,则 receiver 直接存储那个变量;若变量类型大于 1 个机器字,则 Go 底层会
在堆上申请空间存储那个变量的副本,然后 receiver 存储那个副本的地址,即此时 receiver 是个指向变量副本的
指针)。而由变量实现的接口 method(s)组成的 interface table 的指针会填充到 ai 的 method table ptr 字段。当
ai 被赋值为另一个变量后,其 receiver 和 method table ptr 会更新为新变量的相关值。
关于 interface 类型内部实现细节,可以参考 GoLang 官网 Blog 推荐过的一篇文章“Go Data Structures: Inter
faces”,写的很清楚,强烈推荐。
所以,如果某个函数的入参是个 interface 类型时,任何实现了该 interface 的变量均可以作为合法参数传入且函数
的具体行为会自动作用在传入的这个实现了 interface 的变量上,这不正是类似于 C++中多态的行为吗?
这正是 Interface 类型在 Go 语言中的威力。
引用<The Way to Go>一书第 11.5 节对 interface 类型的总结如下,值得每个 Go 学习者理解:
An interface is a kind of contract which the implementing type(s) must fulfill. Interfaces describe the beh
aviorof types, what they can do. They completely separate the definition of what an object can do from
how it does it, allowing distinct implementations to be represented at different times by the same interf
ace variable, which is what polymorphism essentially is.
Writing functions so that they accept an interface variable as a parameter makes them more general.
3、Interface “多态”特性实例
剩余13页未读,继续阅读
LauraKuang
- 粉丝: 17
- 资源: 335
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0