func ShowMethod(i interface{}) {     v := reflect.TypeOf(i)     elemTyp := v.Elem()     n := elemTyp.NumMethod()     if n == 0 {         fmt.Printf("%s's 方法为空!\n", elemTyp)         return     }     fmt.Printf("%s's 方法:\n", elemTyp)     for j := 0; j < n; j++ {         fmt.Println("-", elemTyp.Method(j).Name)     }     fmt.Printf("\n") } type Interface interface {     X1()     X2() } type T struct{} func (t T) X1()  {} func (t *T) X2() {} func main() {     var t T     var pt *T     ShowMethod(&t)     ShowMethod(&pt)     ShowMethod((*Interface)(nil)) }

输出如下

main.T's 方法:

- X1

*main.T's 方法:

- X1

- X2

main.Interface's 方法:

- X1

- X2

可以看到

1 T类型的方法集中只有X1,无法成为与Interface类型的方法的超集

2 *T类型的方法集合是 X1,X2,*T没有直接实现X1,但X1仍然是*T类型的方法合集中。这符合Go的规范:类型*T的方法集合包含所有接收者为T和*T类型的方法。因此,pt才能赋值给Interface类型变量。

接收者选择类型时需要考虑的要点

1 是否支持将T类型实例赋值给某个接口类型变量。

2 如果需要支持,就要实现接收者为T类型的接口类型方法集合中的所有方法。

2. 类型嵌入与方法集合

1) 接口类型中嵌入接口类型

// $GOROOT/src/io/io.gotype 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}type ReadWriteCloser interface {        Reader        Writer        Closer}func main() {     ShowMethod((*io.Writer)(nil))     ShowMethod((*io.Reader)(nil))     ShowMethod((*io.Closer)(nil))     ShowMethod((*io.ReadWriter)(nil))     ShowMethod((*io.ReadWriteCloser)(nil)) }

io.Writer's 方法:

- Write

io.Reader's 方法:

- Read

io.Closer's 方法:

- Close

io.ReadWriter's 方法:

- Read

- Write

io.ReadWriteCloser's 方法:

- Close

- Read

- Write

通过嵌入其他接口而生成的新接口类型ReadWriteCloser的方法集合包含了被嵌套接口类型io.Reader的方法集合。

注:当被嵌入接口有名字重复的时候,新的接口会报错。

2) 结构体类型中嵌入接口类型

在结构体类型中嵌入接口类型后,该结构体类型的方法集合中将包含被嵌入的接口类型的方法集合。

当多个接口类型且这些接口类型的方法集合存在交集的时候,嵌入了其他接口类型的结构体类型的实例在调用方法时,Go选择方法次序:

1 优先选择结构体自身实现的方法;

2 如果结构体自身并未实现,将查找结构体中的嵌入结构类型的方法集中是否有该方法,如果有,则提升为结构体的方法。

当多个接口包含相同方法的时候,当调用的时候会报错,

说不明确的调用。

3. 类型别名的方法集合

type T struct{} func (T) X1()  {} func (*T) X2() {} type Interface interface {     X1()     X2() } type T1 T type Interface1 Interface func main() {     var t T     var pt *T     var t1 T1     var pt1 *T1     ShowMethod(&t)     ShowMethod(&t1)     ShowMethod(&pt)     ShowMethod(&pt1)     ShowMethod((*Interface)(nil))     ShowMethod((*Interface1)(nil)) }

输出如下:

main.T's 方法:

- X1

main.T1's 方法为空!

*main.T's 方法:

- X1

- X2

*main.T1's 方法为空!

main.Interface's 方法:

- X1

- X2

main.Interface1's 方法:

- X1

- X2

从上面结果看:

1 结构类型的别名类型与原来接口类型的方法集合是一致的,如上面 Interface 和 Interface1

2 自定义类型的别名类型则没有“继承”原类型的方法集合,别名类型的方法集合是空的。

byte集合是否相同_Go 语言设计哲学之十八:接口实现方法集合相关推荐

  1. e语言通用进销存源码_Go 语言设计哲学之五:代码风格的唯一标准

    一. gofmt Go 语言设计的目标之一就是解决大型软件系统的大规模开发的问题,解决大型团队的开发问题,Go 核心团队给它起了一个名字叫:规模化(scale). gofmt 是伴随着 Go 语言诞生 ...

  2. frame中src怎么设置成一个变量_Go 语言设计哲学之七:变量声明须一致

    Go 语言,使用变量之前需要先进行变量的声明. var s string = "Golang"n := 666 Go 语言有两类变量 包级别(package varible):在 ...

  3. access导入链接快还是导入表快_Go 语言设计哲学之十三:理解包导入路径的含义...

    Go 语言是使用包(package)作为基本单元来组织源码的, Go 程序就是这些包链接起来而构建的.与C 语言的头文件包含机制相比则是"先进"了许多. 即便是每次编译都是从头开始 ...

  4. C语言编程>第十八周 ⑧ 给定程序中,函数fun的功能是:将形参指针所指结构体数组中的三个元素按num成员进行升序排列。

    例题:给定程序中,函数fun的功能是:将形参指针所指结构体数组中的三个元素按num成员进行升序排列. 注意:请勿改动主函数main与其他函数中的任何内容,仅在横线上填写所需的若干表达式或语句. 代码如 ...

  5. 计算机二级C语言学习笔记(十八)

    上一篇:计算机二级C语言学习笔记(十七) 程序填空题(二) 题型二:平均值 首先求和,然后将和除以项数 ===================================== ========== ...

  6. go channel 缓冲区最大限制_GO语言圣经学习笔记(八)Goroutines和Channels

    奋斗鸭!Day97 知识点 goroutinue 基本用法 golang非常深度的简化了goroutinue的使用方法,异常简单,门槛降低很多 // goroutinue 使用非常简单go f() G ...

  7. C语言编程>第二十八周 ① 多功能进制转换器设计

    多功能进制转换器设计 这两天花时间用C语言编写了一个多功能进制转换器,可以实现十进制数到二进制数的转换.十进制数到八进制数的转换.十进制数到十六进制数的转换.二进制数到八进制数的转换.二进制数到十进制 ...

  8. 单片机c语言设计一个按键控制八个流水灯,单片机按键如何控制流水灯

    第四段子程序 下面是汇编语言写的程序代码 ORG 0000H LJMP START LED EQU P0 START: MOV P2,#00H MOV LED,#0FFH        ;LED灭 M ...

  9. 2021年大数据常用语言Scala(二十八):scala面向对象 MAVEN依赖和类

    目录 scala面向对象 MAVEN依赖 类 - 掌握 创建类和对象 - 掌握 getter/setter - 了解 类的构造器 - 掌握 scala面向对象 MAVEN依赖 <?xml ver ...

最新文章

  1. JWT Authentication Tutorial: An example using Spring Boot--转
  2. 计算机系统的层次结构是缺一不可的吗,第1章 计算机组成与结构绪论.ppt
  3. matplot 绘图总结
  4. java thread类_java多线程之Thread类
  5. Swift 的变化:从 2.2 到 3.0 会带来什么
  6. 利用非循环顺序队列采用广度搜索法求解迷宫问题(一条路径)
  7. ios图片剪切之圆形头像
  8. 使用 JavaScript 生成二维码 —— QRCode.js
  9. 大数据初学者的福利——Hadoop快速入门教程
  10. 中科微GPS模块使用教程 ATGM332D ATGM336H GSP模块 单片机程序 C程序
  11. 一文了解.Net Core 3.1 Web API基础知识
  12. vue——微信二维码显示vue-qr/qrcodejs2
  13. 贝塞尔曲线及实践案例
  14. 独木舟上的旅行java_独木舟上的旅行
  15. vue h5端实现富文本图片预览(基于 Vant 的 ImagePreview 组件)
  16. 数据库结构与算法基础
  17. 【FPGA教程案例12】基于vivado核的复数乘法器设计与实现
  18. sql STUFF用法
  19. 「java」重载重写多态
  20. 2022.2.28 心情日记

热门文章

  1. 基于JAVA+SpringMVC+Mybatis+MYSQL的病例管理系统
  2. 计算机注册表管理,如何打开计算机注册表编辑器
  3. CodeForces Contest #1114: Round #538 (Div. 2)
  4. 【转载】通往性能优化的天堂-地狱 JOIN方法说明
  5. HLSL Tips 1:如何把输入映射到输出像素
  6. 初学者python笔记(os模块、sys模块)
  7. 在Python程序中设置函数最大递归深度
  8. 使用with关键字让你的Python代码更加Pythonic
  9. linux定时刷新命令结果,51CTO博客-专业IT技术博客创作平台-技术成就梦想
  10. oracle视图分页查询,关于Oracle数据库各种操作大全(四)分页(视图)