正文:
类型系统:
类型是一个语言的类型体系结构,一个典型的类型系统应该包含如下基本命令内容:基础类型(byte,int,bool,float);复合类型(数组,结构体,指针等);可以指向任意对象的类型(Any类型);值语义和引用语义;面向对象,即所有面向对象的类型;接口;
Go语言大多数类型都是值语义,并且可以包含对应的操作方法,在需要的时候,你可以给任意类型增加方法,而在实现某个接口时,无需从该接口继承GO(本身就不支持棉线对象思想中的继承语法),只需要实现该接口的所有方法即可。任何类型都可以被Ang类型引用。Any类型就是空接口,即interface{ }。
为类型添加方法
在Go语言中,你可以给任意类型(包括内置类型,但不包括指针类型)添加相应的方法,例如:
//我们定义了一个新类型Integer,他和int没有本质不同只是他内置的int增加了Less()了方法 type Integer int func(a Integer)Less(b Integer bool)bool{ return a<b } //这样实现了Integer类型之后,就可以像普通类那样使用 func main(){ var a Integer-1 if a.Less(2){ fmt.Println(a,"Less 2") } }
Go语言中,如果要求对象必须用指针传递,这时会有额外的成本,因为有时对象很小,用值传递并不划算,只有需要修改对象时才需要使用指针。
func(a *Integer)Add*(b Integer){ *a +=b }
Go语言和C语言一样,类型都是基于值传递的,要想修改变量的值只能传递指针。
值语义和引用语义
值语音和引用语义的差别在于赋值如:b=a 和b.Modify()如果b的修改不会影响a的值,那么它属于值类型,如果影响了a的值那么此类型是引用类型。Go语言大多类型都是基于值语义。
GO语言的数组和基本类型没有区别,是一个很纯粹的值类型,例如:
//输出 [1,2,3] [1,3,3] var a =[3] int {1,2,3} var b=a b[1]++ fmt.Println(a,b) //表明了b=a是数组内容的完整复制。要想表达引用需要使用引用类型。 //输出 [1,2,3][1,3,3] var a=[3]int{1,2,3} var b=&a b[1]++ fmt.Println(a,*b) //这表明了b=&a是数组内容的引用,变量b的类型不是[3]int,而是*[3]int类型。
结构体
Go语言的结构体(struct)和其他语言的(class)有同等的地位,但Go语言放弃了包括继承在内的大量面向对象的特征,只留下组合(composition)这个基础的特性。其实GO中的结构体平淡无奇,接下来定义一个举行类型。
type Rect struct{ x,y float64 width,height,float } //定义成员方法Area()计算面积 func (r *Rect)Area() float64{ return r.width * r.height } //可以看出,Go语言中的结构体的使用方法与C语言没有明显不同
初始化
定义了Rect类型之后,我们可以通过以下几个方法实现:
rect1:=new(Rect) rect2:=&Rect{} rect3:=&Rect{0,0,100,200} rect4:=&Rect{width:100,height:200}
在Go语言中,为进行显性初始化的变量都会初始化为该类型的零值,例如bool类型的零值为false,int类型的零值为0,string类型的零值为空字符串。Go语言中没有构造函数的概念,对象的创建通常交由一个全局的创建函数来完成,以NewXX来命名,表示构造函数。
//这真的很简单 func NewRect{x,y,width,height float64} *Rect{ return &Rect{x,y,width,height}
匿名组合
确切的说,Go语言也提供了继承,但是采用了组合的文法,所以称为匿名组合:
type Base struct{ Name string } func (base *Base) Foo() {...} func (base *Base) Bar() {...} type Foo struct{ Base ... } func (foo *Foo)Bar(){ foo.Base.Bar() }
以上代码定义了一个Base类实现了Foo()和Bar()两个成员方法,然后定义一个Foo类,该类从Base类”继承”并改写了Bar()方法(实现时先调用基类的Bar()方法)。在”派生类”Foo没有该写”基类”base的成员方法时,该方法就被”继承”,例如在上面例子中,调用foo.Foo()和调用foo.Base.Foo()效果一致。
可见性:
GO语言对关键字的增加非常吝啬,其中没有private,protected,public等关键字。遵循的是大小写对其他package开放的规则。Go的可访问性是包级别而非类级别的,这说明同包内可以彼此访问私有成员。
接口:
Go语言的主要设计者之一罗布派克曾经说,果果只能选择一个GO语言的特性移植到其他语言中,他会选择接口。如果说goroutine和channel是并发模型的基石,那么接口就是整个类型系统的基石,让Go语言在基础编程哲学上探索到前所未有的高度。
传统面向对象的语言的接口都是侵入式接口,必须明确指定继承实现的接口。而GO是一种非侵入式的接口。
在Golang中,一个类只需实现了接口要求的所有函数,我们就说这个类实现了接口。
后记:
由于内容过多,我还需要一些时间来理解,明天继续学习笔记,接着借口来 = =,内容好多,话说指针根本不会撸之前 = =。