go语言包含但不限于int32,float32,chan,map,slice等内建类型,同时为了能让用户定义自己的类型,go语言为我们提供了struct和interface这两种好用的工具
结构体(Struct)
和C语言的struct相似,在go语言中,我们依然用struct来声明一个结构体比如:
type gameObject struct{ name string}
以上代码声明了一个名为gameObject的结构体,该结构体包含类型为string的字段name。
在go语言中,所有的类型名都是放在变量后面的,这也是go语言跟C/C++,JAVA,C#等语言区别比较大的地方。 既然有了struct,那有没有class呢? 没有class,go语言中的“面向对象”概念和上面提到的几种语言是有很大区别的,后面会讲到嵌入(Embedding)
go语言中的“继承”和其他语言中的继承有很大区别,比如:
type player struct{ gameObject}
这是一种“继承”的写法,在go语言中这种方式叫做“嵌入”(embed),此时player类型就拥有了gameObject类型的name变量
方法(Method)
在go语言中,我们可以为自定义类型定义类型相关的方法,比如:
func (p *player) Name() string{ return p.name}
上面的代码为player这个自定义类型声明了一个名为Name的方法,该方法返回一个string。值得注意的是(p *player)
这段代码指定了我们是为player创建方法,并将调用该方法的实例指针当作变量p传入该函数,如果没有(p *player)
这段代码,这个方法就变成了一个普通的全局函数。
接口(interface)
go语言中接口的概念和其他语言中的接口概念非常相似,比如:
type challenger interface { Name() string Attack()}
上面的代码声明了一个名为challenger的接口,这个接口包含2个函数(行为)Name() string
和Attack()
,在go语言中,只要实现了接口中定义的全部函数,就认为实现了该接口,所以所有的类型都实现了interface{}
接口,interface{}
类型的变量也被当作go语言中的void*
指针来使用。
接口的运用
参考以下代码:
package main import "fmt"type gameObject struct { name string}func (o *gameObject) Name() string{ return o.name}func (o *gameObject) Attack() { fmt.Printf("GameObject %s do not know how to attack\n", o.name)}type player struct { gameObject}func (p *player) Attack(){ fmt.Printf("player %s attacks\n", p.name)}type monster struct { gameObject}type challenger interface { Name() string Attack()}func main(){ p := &player{gameObject : gameObject{name:"devgl"}} m := &monster{gameObject : gameObject{name:"slime"}} Attack(p) Attack(m)}func Attack(c challenger) { c.Attack()}
上面这段代码声明了两个内嵌gameObject自定义类型player和monster,其中,gameObject实现了challenger接口的所有函数,因此gameObject实现了challenger接口,那么,我们可以说player和monster这两个自定义类型也实现了该接口。除此之外,player类型定义了自己的Attack函数实现,在main函数中,我们创建了p,m两个对象分别对应player和monster,并将对象的指针传入Attack全局函数。这里可以注意到Attack全局函数的参数是一个challenger接口,而player,monster都实现了这个接口,所以这样传值没有问题,程序输出:
player devgl attacksGameObject slime do not know how to attack
注意第二行是m.Attack()的输出,因为monster没有定义自己的Attack函数,所以go语言帮我们找到了gameObject的Attack实现。
需要注意的要点
- 学习go语言时,切忌将其他OO语言的概念强加到go语言中,要以go语言的方式去思考和编写代码,本文中用了很多OO的概念和词汇旨在比较通俗的介绍go语言的基本概念,而不是要读者站在其他语言的角度去思考go语言
- interface是go语言中非常重要的概念和经常使用的工具,为了更好的理解go语言的interface的概念,有条件的读者可以参阅中关于interface的描述