接口是 Go 语言整个类型系列的基石,C++,Java 使用"侵入式"接口,主要表现在实现类需要明确声明自己实现(implement)了某个接口。这种强制性的接口继承方式是面向对象编程思想发展过程中一个遭受相当多质疑的特性。Go 语言采用的是“非侵入式接口",Go 语言的接口有其独到之处:只要类型 T 的公开方法完全满足接口 I 的要求,就可以把类型 T 的对象用在需要接口 I 的地方,所谓类型 T 的公开方法完全满足接口 I 的要求,也即是类型 T 实现了接口 I 所声明的所有方法。会一点 Java 的朋友应该知道,Java 中的接口实现了多态这一作用,Go 语言中的接口也不例外。
2、初识接口
2.1、接口的定义
type interfaceName interface{funcName1(params...) dataType...funcName2(params...) dataType...//省略若干方法}
type Person interface{Talk()stringEat(what string)}type Man struct{
Message string}type Woman struct{
Message string}func(m Man)Talk()string{return m.Message +"在说话"}func(m Man)Eat(what string){
fmt.Printf("%s说%s真好吃", m.Message, what)}func(w Woman)Talk()string{return w.Message +"在说话"}funcmain(){
m := Interface.Man{Message:"男人"}//w := Interface.Woman{Message: "女人"}var p Interface.Person
p = m
p.Eat("火锅")
fmt.Println(p.Talk())//p = w//报错:cannot use w (type Interface.Woman) as type Interface.Person in assignment:Interface.Woman does not implement Interface.Person (missing Eat method)}
type Man struct{
Message string
Name string}funcDoSth(p interface{}){//p 可以存储任意类型的值
fmt.Println(p)}funcmain(){
Interface.DoSth(1)//可以存储基本数据类型
m :=&Interface.Man{
Message:"男人",
Name:"嬴政",}
Interface.DoSth(*m)//可以存储结构体值
Interface.DoSth(m)//可以存储指针}
运行上述代码,输出如下:
1
{男人 嬴政}
&{男人 嬴政}
2.4、类型断言
所谓类型断言,就是判断一个接口,它存储的数据到底是什么类型的,比如我要写一个函数,这个函数接受一个空接口作为参数,这个函数的作用是,判断传进来的接口存储的是 Man 结构体还是 Woman 结构体,如果是 Man 结构体,那么请去男厕所,如果是 Woman 结构体,请去女厕所,看代码:
funcToilet(p interface{}){
fmt.Println("欢迎来到智能厕所")if man, ok := p.(Man); ok {
fmt.Printf("%s先生,请去左手边的男厕所\n", man.Name)}elseif woman, ok := p.(Woman); ok {
fmt.Printf("%s女士,请去右手边的女厕所\n", woman.Name)}else{
fmt.Println("你是男人还是女人?")}}funcmain(){
man := Interface.Man{
Message:"男人",
Name:"嬴政",}
woman := Interface.Woman{
Message:"女人",
Name:"吕雉",}
Interface.Toilet(man)
Interface.Toilet(woman)
Interface.Toilet("机器人")}
type coder interface{code()debug()}type Gopher struct{
language string}func(g Gopher)code(){
fmt.Printf("I am coding %s language.\n", g.language)}func(g *Gopher)debug(){
fmt.Printf("I am debugging %s language.\n", g.language)}funcTransValueTest(){//var c coder = Gopher{language: "go"} 这里会报错,错误信息如下//cannot use Gopher literal (type Gopher) as type coder in assignment:Gopher does not implement coder (debug method has pointer receiver)//这样改就正确了:var c coder =&Gopher{language:"go"}}