Go 嵌入类型
文章转载地址:https://www.flysnow.org/2017/04/06/go-in-action-go-embedded-type.html
嵌入类型或嵌套类型,这是一种可以把已有类型的声明嵌入到新的类型里的一种方式,这种功能对代码复用非常
重要
在其他语言中,有继承的概念,但是在 Go 语言中没有继承的概念,Go 提倡的代码复用的方式是组合,所以,这
也是嵌入类型的意义所在,组合不是继承,所以,Go 才会更加灵活
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int,err error)
}
type Closer interface {
Close() error
}
type ReadWriter interface {
Reader
Writer
}
type ReadCloser interface {
Reader
Closer
}
type WriteCloser interface {
Writer
Closer
}
上面是标准 io 包里,我们常用的接口,可以看到 ReadWriter 接口是嵌入 Reader、Writer 接口组合而成的新接口,这样
我们就不用在重复的定义被嵌入接口的方法,直接通过嵌入就可以了。嵌入类型同样适用于结构体类型,看下面例子:
type user struct {
name string
email string
}
type admin struct {
user
level string
}
嵌入后,被嵌入的类型称之为内部类型,新定义的类型称之为外部类型,这里 user 就是内部类型,而 admin 是外部类型
通过嵌入类型,与内部类型相关的字段、方法、标识符等都会被外部类型所拥有,就像外部类型自己的一样,这样就达到了
代码快捷复用组合的目的
同时,外部类型还可以添加自己的方法,字段等,可以很方便的扩展外部类型的功能
type user struct {
name string
email string
}
type admin struct {
user
level string
}
func main() {
ad := admin{user{"张三","zhangsans@qq.com"},"管理员"}
fmt.Println("可以直接调用,名字是:",ad.name)
fmt.Println("也可以通过内部类型调用:",ad.user.name)
fmt.Println("但新增的属性只能直接调用:",ad.level)
}
上面是嵌入类型的使用,在初始化的时候,我们采用的是字面值的方式,先初始化 user 这个内部类型,再初始化
新增的 level 属性
对于内部类型的属性和方法访问上,我们可以采用外部类型直接访问,也可以通过内部类型进行访问,但是我们为
外部类型新增方法属性字段,只能使用外部类型访问,因为内部类型没有这些
当然,外部类型也可以声明同名的字段或方法,来覆盖内部类型,这种情况方法比较多,以方法为例:
type user struct {
name string
email string
}
type admin struct {
user
level string
}
func (u user) sayHello() {
fmt.Println("Hello,I am a user")
}
func (a admin) sayHello() {
fmt.Println("Hello,I am a admin")
}
func main() {
ad := admin{user{"张三","zhangsans@qq.com"},"管理员"}
ad.user.sayHello()
ad.sayHello()
}
内部类型 user 有一个 sayHello 方法,外部类型对其进行了覆盖,同名重写 sayHello,然后在 main 方法分别访问这两个
类型的方法,打印输出:
Hello,I am a user
Hello,I am a admin
从上面的输出可以看出,方法 sayHello 被覆盖了
嵌入类型还有一个强大的地方就是:如果内部类型实现了某个接口,那么外部类型也被认为实现了这个接口,如下示例:
type Hello interface {
hello()
}
type user struct {
name string
email string
}
type admin struct {
user
level string
}
func (u user) hello() {
fmt.Println("Hello, I am a user")
}
func sayHello(h Hello) {
h.hello()
}
func main() {
ad := admin{user{"张三","zhangsans@qq.com"},"管理员"}
sayHello(ad.user) // 使用 user 作为参数
sayHello(ad) // 使用 admin 作为参数
}
新增一个 Hello 接口,然后让 user 类型实现这个接口,最后定义了一个 sayHello 方法,它接受一个 Hello 类型的
参数,最后我们在 main 函数调用的时候,发现不管是 user 类型吧,还是 admin 类型作为参数传递给 sayHello 都能正
常调用,这里就能说名 admin 接口实现了接口 Hello,但是又没有显示声明 admin 实现,所以这个实现是通过内部类型
user 实现的,因为 admin 包含了 user 所有方法和字段,所以也就实现了这个接口
Go 嵌入类型的更多相关文章
- Go语言嵌入类型
一.什么是嵌入类型 先看如下代码: type user struct { name string email string } type admin struct { user // Embedded ...
- Go 语言中的方法,接口和嵌入类型
https://studygolang.com/articles/1113 概述 在 Go 语言中,如果一个结构体和一个嵌入字段同时实现了相同的接口会发生什么呢?我们猜一下,可能有两个问题: 编译器会 ...
- golang拾遗:嵌入类型
这里是golang拾遗系列的第三篇,前两篇可以点击此处链接跳转: golang拾遗:为什么我们需要泛型 golang拾遗:指针和接口 今天我们要讨论的是golang中的嵌入类型(embedding t ...
- go接口及嵌入类型例子
书上看的.慢慢领会.. package main import ( "fmt" ) type notifier interface { notify() } type user s ...
- Go嵌入类型及内部提升样例
这个有点新鲜哟... package main import ( "fmt" ) type notifier interface { notify() } type user st ...
- [C#]嵌入互操作类型
嵌入互操作类型(Embed Interop Types) 运用office编程调用Excel 的PIA时Microsoft.Office.Interop.Excel.dll时会产生如下问题: 1.提示 ...
- Go语言规格说明书 之 接口类型(Interface types)
go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...
- 九.Protobuf3特殊类型
Protobuf3 Any类型 Any消息类型允许您将消息作为嵌入类型,而不需要它们 .proto定义.Any包含任意序列化的消息(字节),以及一个URL,该URL充当该消息的全局唯一标识符并解析为该 ...
- 学习Spring-Data-Jpa(五)---可嵌入对象和元素集合的使用
1.场景一:地址信息(省.市.县.详细地址)在很多实体中都需要,比如说作者有地址,订单也有地址,但是他们的地址并不能独立与他们存在,所以地址不能映射为实体,那么我们就需要在作者实体和订单实体中都添加这 ...
随机推荐
- .net js有数据 但是跳转不到操作页
首先看的是:js 的 model 传了 两个参数 在接着打开操作页 可以看到,这一页有三个参数.id是可以自动生成的,所以不让他显示,去掉 如上就可以了 ,传的参数数量不对 ,下次注意的撒!
- robotframework接口之上传图片
python-requests及robotframework-RequestsLibrary实现multipart/form-data接口上传文件. 如Fiddle抓包截图: 实现如截图: 不要自己在 ...
- weblogic的基础安装
安装java环境 不能使用centos自带的openjdk 必须使用源码安装 把下载的jdk-8u181-linux-x64.tar 解压到 /usr/src目录下 tar zxvf jd ...
- C# 字典Dictionary
Dictionary<TKey, TValue> 泛型类提供了从一组键到一组值的映射.通过键来检索值的速度是非常快的,接近于 O(1),这是因为 Dictionary<TKey, T ...
- 10个Python基础练习项目,你可能不会想到练手教程还这么有趣
美国20世纪最重要的实用主义哲学家约翰·杜威提出一个学习方法,叫做:Learning By Doing,在实践中精进.胡适.陶行知.张伯苓.蒋梦麟等都曾是他的学生,杜威的哲学也影响了蔡元培.晏阳初等人 ...
- Cache Aside Pattern
Cache Aside Pattern 即旁路缓存是缓存方案的经验实践,这个实践又分读实践,写实践 对于读请求 先读cache,再读db 如果,cache hit,则直接返回数据 如果,cache m ...
- 一个比较难忘的BUG
本学期开设了软件测试课程,在课上有讨论到bug,想到bug,真是很令人头疼的东西,相信每个程序都多多少少会有几个头疼的bug. 初学java时写过一个字符串判断的循环,之前学的C++字符类型用“==” ...
- WEB服务器,TOMCAT和servlet之间的关系
WEB服务器,TOMCAT和servlet之间的关系 什么是WEB服务器Web服务器是指能够为发出请求的浏览器提供文档的程序.服务器是 一种被动程序,只有浏览器发出请求的时候才会响应.应用层使用 的是 ...
- 判断文件的编码 python
import chardet import string path1= r'C:\Users\25456\Desktop' path = path1 + r'\深度学习.txt' with open( ...
- Nginx Install 记录
一.安装编译工具及库文件 yum -y install gcc yum -y install gcc-c++ yum -y install zlib; yum -y install pcre-deve ...