上一篇文章 主要学习了Go语言的切片以及Map。本篇文章主要学习的是Go语言中的接口、反射以及错误和异常处理。
接口:
回想一下,在Java中,有父类和子类的说法,父类主要是提供抽象的公共方法让子类基于此拓展自身的功能。Java还有抽象类和接口
那么,在Go语言中也提供了一种数据类型,接口。GO语言的接口是把所有的具有共性的方法定义在一起,其他类型只要实现了接口内的方法就是实现了这个接口。(是不是很类似Java的接口?)
GO语言定义接口的语法格式:
type 接口名 interface {
接口方法();
}
GO语言接口实战:
为了看到效果,首先我们定义一个吃东西的接口,由于中西方饮食文化的差异,我们用筷子,歪果仁用刀叉,针对这种差异我们可以定义两个结构体;我们让这两个结构体都实现吃的接口,由于接口不能直接new 但是可以new子类(也就是实现接口的结构体),因此可以有以下代码:
好了,我们还可以继续拓展:
结果如下:
拓展:空interface
空interface(interface{})不包含任何的method,正因为如此,所有的类型都实现了空interface。空interface对于描述起不到任何的作用(因为它不包含任何的method),但是空interface在我们需要存储任意类型的数值的时候相当有用,因为它可以存储任意类型的数值。它有点类似于C语言的void*类型。如下图
一个函数把interface{}作为参数,那么他可以接受任意类型的值作为参数,如果一个函数返回interface{},那么也就可以返回任意类型的值。任意类型的值这样的好处是方便拓展
总之:interface就是一组抽象方法的集合,它必须由其他非interface类型实现,而不能自我实现。Go通过interface实现了duck-typing:即"当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子"。
反射:
Go语言实现了反射(最后看来跟Java的反射有异曲同工之效),所谓反射就是能检查程序在运行时的状态动态,拿到属性值并可以赋值的一种机制。GO语言使用反射功能会用到reflect包。
GO语言使用反射一般分为以下三步:
A:首先需要把需要反射的对象转化成reflect对象(reflect.Type或者reflect.Value,根据不同的情况调用不同的函数)。这两种获取方式如下:
t := reflect.TypeOf(i) //得到类型的元数据,通过t我们能获取类型定义里面的所有元素
v := reflect.ValueOf(i) //得到实际的值,通过v我们获取存储在里面的值,还可以去改变值
B:转为reflect对象后,我们可以将reflect对象转化成相应的值,例如
tag := t.Elem().Field(0).Tag //获取定义在struct里面的标签字段
name := v.Elem().Field(0).String() //获取存储在第一个字段里面的值
C:反射的字段必须是可修改的(也就是Java中反射的API,允许反射)
下面是一个简单的反射例子,通过获取x的值,然后反射调用,在修改值的操作:
错误和异常处理:
错误指的是可能出现问题的地方出现了问题,比如打开一个文件时失败,这种情况在人们的意料之中
异常指的是不应该出现问题的地方出现了问题,比如引用了空指针、数组越界、除数为0等等
因此:
Go引入error接口作为错误处理的标准模式,如果函数要返回错误,那么返回值类型中要包含error;
Go引入两个内置函数panic和recover来触发和终止异常处理流程,同时引入关键字defer来延迟执行defer后面的函数。
基于错误和异常的处理这里推荐一篇非常不错的博客:
本篇文章关于Go语言中的接口、反射以及错误和异常处理的内容基本上就结束了。
如果这篇文章对你有帮助,希望各位看官留下宝贵的star,谢谢。
Ps:著作权归作者所有,转载请注明作者, 商业转载请联系作者获得授权,非商业转载请注明出处(开头或结尾请添加转载出处,添加原文url地址),文章请勿滥用,也希望大家尊重笔者的劳动成果