初步解读Golang中的接口相关编写方法

2024-06-05 12:23:22

初步解读Golang中的接口相关编写方法

概述
如果说goroutine和channel是Go并发的两大基石,那么接口是Go语言编程中数据类型的关键。在Go语言的实际编程中,几乎所有的数据结构都围绕接口展开,接口是Go语言中所有数据结构的核心。
Go语言中的接口是一些方法的集合(method set),它指定了对象的行为:如果它(任何数据类型)可以做这些事情,那么它就可以在这里使用。

接口的定义和使用

比如

复制代码代码如下:

type I interface{
    Get() int
    Put(int)
 
}

这段话就定义了一个接口,它包含两个函数Get和Put

好了,我的一个接口实现了这个接口:

复制代码代码如下:

type S struct {val int}
func (this *S) Get int {
    return this.val
}
func (this *S)Put(v int) {
    this.val = v
 
}

这个结构S就是实现了接口I

Go中interface的写法

下面看几个interface的例子:

复制代码代码如下:

func SomeFunction(w interface{Write(string)}){
    w.Write("pizza")
 
}

这个例子中,直接将interface定义在参数中,很特别…

复制代码代码如下:

func weirdFunc( i int ) interface{} {
  if i ==  0 {
    return "zero"
  }
  return i;
}

接口赋值
我们可以将一个实现接口的对象实例赋值给接口,也可以将另外一个接口赋值给接口。

(1)通过对象实例赋值

将一个对象实例赋值给一个接口之前,要保证该对象实现了接口的所有方法。考虑如下示例:

复制代码代码如下:

type Integer int
func (a Integer) Less(b Integer) bool {
 return a < b
}
func (a *Integer) Add(b Integer) {
 *a += b
}

type LessAdder interface { 
 Less(b Integer) bool 
 Add(b Integer)
}

var a Integer = 1
var b1 LessAdder = &a //OK
var b2 LessAdder = a   //not OK

b2的赋值会报编译错误,为什么呢?还记得<类型方法>一章中讨论的Go语言规范的规定吗?

The method set of any other named type T consists of all methods with receiver type T. The method set of the corresponding pointer type T is the set of all methods with receiver T or T (that is, it also contains the method set of T).
也就是说*Integer实现了接口LessAdder的所有方法,而Integer只实现了Less方法,所以不能赋值。

(2)通过接口赋值

复制代码代码如下:

var r io.Reader = new(os.File)
        var rw io.ReadWriter = r   //not ok

var rw2 io.ReadWriter = new(os.File)
        var r2 io.Reader = rw2    //ok

因为r没有Write方法,所以不能赋值给rw。

接口嵌套
我们来看看io package中的另外一个接口:

复制代码代码如下:

// ReadWriter is the interface that groups the basic Read and Write methods.
type ReadWriter interface {
 Reader
 Writer
}

该接口嵌套了io.Reader和io.Writer两个接口,实际上,它等同于下面的写法:

复制代码代码如下:

type ReadWriter interface {
Read(p []byte) (n int, err error) 
Write(p []byte) (n int, err error)
}

注意,Go语言中的接口不能递归嵌套,

复制代码代码如下:

// illegal: Bad cannot embed itself
type Bad interface {
 Bad
}

// illegal: Bad1 cannot embed itself using Bad2
type Bad1 interface {
 Bad2
}
type Bad2 interface {
 Bad1
}

空接口(empty interface)
空接口比较特殊,它不包含任何方法:

复制代码代码如下:

interface{}

在Go语言中,所有其它数据类型都实现了空接口。

复制代码代码如下:

var v1 interface{} = 1
var v2 interface{} = "abc"
var v3 interface{} = struct{ X int }{1}

如果函数打算接收任何数据类型,则可以将参考声明为interface{}。最典型的例子就是标准库fmt包中的Print和Fprint系列的函数:

复制代码代码如下:

func Fprint(w io.Writer, a ...interface{}) (n int, err error) 
func Fprintf(w io.Writer, format string, a ...interface{})
func Fprintln(w io.Writer, a ...interface{})
func Print(a ...interface{}) (n int, err error)
func Printf(format string, a ...interface{})
func Println(a ...interface{}) (n int, err error)

注意,[]T不能直接赋值给[]interface{}

复制代码代码如下:

t := []int{1, 2, 3, 4}
        var s []interface{} = t

编译时会输出下面的错误:

cannot use t (type []int) as type []interface {} in assignment

我们必须通过下面这种方式:

复制代码代码如下:

t := []int{1, 2, 3, 4}
s := make([]interface{}, len(t))
for i, v := range t {
    s[i] = v
}

转载于:https://blog.51cto.com/jianghai/1734528

初步解读Golang中的接口相关编写方法相关推荐

  1. sklearn中FastICA接口的使用方法

    sklearn中FastICA接口的使用方法 ICA算法的数学原理 FastICA算法的实现过程及其python实现 sklearn中FastICA接口的使用方法 完整代码 ICA算法的数学原理 参考 ...

  2. golang中的接口实现(二)

    指针类型 vs 值类型实现接口 package mainimport ("fmt" )// 定义接口 type Describer interface {Describe() }/ ...

  3. golang 切片 接口_如何理解Golang中的接口?

    个人认为,要理解 Go 的接口,一定先了解下鸭子模型. 鸭子模型 那什么鸭子模型? 鸭子模型的解释,通常会用了一个非常有趣的例子,一个东西究竟是不是鸭子,取决于它的能力.游泳起来像鸭子.叫起来也像鸭子 ...

  4. 使对象具有ES6中Iterator接口的实现方法

    es6中只有具有iterator接口的数组或者类数组(arguments)都可以使用for of来循环,但是对于对象来说不行,可以利用迭代器中的原理来给对象生成一个迭代器,实现让对象可以使用for o ...

  5. Golang中各种永远阻塞的方法

    在Golang中各种永远阻塞的姿势 Go的运行时的当前设计,假定程序员自己负责检测何时终止一个goroutine以及何时终止该程序. 可以通过调用os.Exit或从main()函数的返回来以正常方式终 ...

  6. 接口测试用例编写方法

    接口测试用例编写可以从四个方面入手:功能.逻辑业务.异常测试.安全

  7. api 接口开发理论 在php中调用接口以及编写接口

    如: http://localhost/openUser.php?act=get_user_list&type=json 在这里openUser.php相当于一个接口,其中get_user_l ...

  8. 在php中调用接口以及编写接口

    如: http://localhost/openUser.php?act=get_user_list&type=json 在这里openUser.php相当于一个接口,其中get_user_l ...

  9. golang中的接口

    接口 在go中,接口是一个自定义类型 接口类型是一个抽象类型,他不会暴露他代表的对象的内部值的结构和这个对象支持的基础操作的集合,他们只会展示出自己的方法.因此接口类型不能将他实例化 定义 type ...

最新文章

  1. php mysql zend linux_在Linux系统中安装Apache+MySQL+php+phpMyAdmin+Zend
  2. iOS - 图文混排技术方案分享
  3. 你花了多久弄明白架构设计?kafka日志清理
  4. 零基础学python看什么书-零基础学python推荐几本python学习的书籍
  5. javascript”面向对象编程”- 1万物皆对象
  6. k8s部署dashboard
  7. Structs框架原理
  8. 在线硬盘存储计算机,【模拟攒机-模拟装机】在线攒电脑-ZOL中关村在线
  9. 如何自制一款智能AI离线语音小夜灯
  10. 软件工程导论——课堂学习笔记
  11. 深度学习中 GPU 和显存分析
  12. 关键20小时,快速学会任何技能
  13. 手机显示DNS服务器异常,DNS服务器异常?
  14. 网易2019实习生招聘-数对
  15. Ubuntu 20.04 boot repair(镜像引导目录修复)
  16. 2020JavaScript技能抽查
  17. erp知识基础-会计
  18. 杰普实训日记 授课内容 第一天 讲师:李春雨
  19. 鼠标右键编辑html文档,鼠标右键菜单编辑方法
  20. SQL在MySQL中是如何执行的

热门文章

  1. ios math 那个头文件_iOS math.h数学函数
  2. 关于hive开窗函数的问题
  3. C#中使用委托、接口、匿名方法、泛型委托实现加减乘除算法
  4. [译]BEAST还是一个威胁吗?
  5. 一千行MySQL学习笔记
  6. ASP.NET自带机制不刷新页面
  7. 将现有网站与Community Server2.0整合解决方案(原创)
  8. Kmeans、Kmeans++和KNN算法比较
  9. 15类Android通用流行框架
  10. 超高性能管线式HTTP请求(实践·原理·实现)