接口
接口,一个比较抽象的概念词,实际上也的确是很抽象的概念。如果要类比,可以将接口视为一种规定或者标准,它会定义好一些函数,然后要求具体的类去实现这些函数。
如果某个类实现了这些函数,你就可以将是这个类的变量赋值给接口变量,然后你就可以使用接口去执行该函数。
这一目标所希望满足的便是在大型项目下的一些需求,例如,我在编写某个函数时,例如比大小,你可以放个接口在这,代码上直接执行比大小接口,而先不实现。在之后,当需要使用这个比大小代码时,你再专门针对情况实现函数,赋值给接口就行了,这样就提升了代码的后续可开发性了。
接口的定义需要用到两个关键字type和interface。如下:
type Human interface {
Profession()
}
这里定义了一个Human接口,Human接口中有Profession函数待实现,接下来我将实现这个函数。
type Student struct{
}
func (s Student)Profession(){
fmt.Println("Im student");
}
这里我就实现具体的Profession函数了。
在main函数中就可以使用这个接口了:
func main(){
var somebody Human
somebody = Student//这里就确定了接口将调用Student类所实现的函数
somebody.Profession()
}
当然了,你也可以创建Teacher类等等,来实现这个Profession函数以执行不同的代码,但相同的是,你都可以通过这个Human接口来创建变量以调用:
func main(){
var somebody Human
somebody = Student//这里就确定了接口将调用Student类所实现的函数
somebody.Profession()
somebody = Teacher
somebody.Profession()//这样就会执行不同的函数了
}
还原为原始类型
接口也提供了函数来还原为原来的类型,那就是类型断言。类型断言并不会直接返回类型,它需要你自己猜它是什么类型:
func main(){
var somebody Human
somebody = Student//这里就确定了接口将调用Student类所实现的函数
s, ok := somebody.(Student)
if ok {
fmt.Println("Yes");
}
}
当然了,如果你在猜它是什么类型之后不去判断有没有断言成功,也就是判断ok是true还是false,Go编译器就会抛出错误。
有两种办法来判断有没有断言成功,一种是对ok值判断:
s, ok := somebody.(Student)
if ok {
fmt.Println("Yes");
}
另外一种是type switch类型分支:
switch v := somebody.(type){
case Student:
fmt.Println("是学生")
default:
fmt.Println("灵活就业")
}
建议在每个类型断言之后都加上判断断言是否成功,不能因为这些小细节导致异常抛出。