在Go语言中,你可以给任意类型(包括内置类型,但不包括指针类型)添加相应的方法,例如:
1 | type Integer int |
C++语言的面向对象之所以让有些人迷惑的一大原因就在于其隐藏的this指针。一旦把隐藏的this指针显露出来,大家看到的就是一个面向过程编程。如果读者了解Python语法,就会知道Python的成员方法中会有一个self参数,它和this指针的作用是完全一样的。
1 | struct Integer { int val; |
go传递指针而不是值的写法:
1 | func (a *Integer) Add(b Integer) { |
C语言中的数组比较特别。通过函数传递一个数组的时候基于引用语义,但是在结构体中定义数组变量的时候基于值语义(表现在为结构体赋值的时候,该数组会被完整地复制)。Go语言中的数组和基本类型没有区别,是很纯粹的值类型
1 | var a = [3]int{1, 2, 3} var b = a |
类的初始化
1 | type Rect struct { |
Go语言也提供了继承,但是采用了组合的文法,所以我们将其称为匿名组合
1 | type Base struct { |
Go语言中符号的可访问性是包一级的而不是类型一级的。如果Go语言符号的可访问性是类型一级的,少不了还要加上friend这样的关键字,以表示两个类是朋友关系,可以访问彼此的私有成员。
在Go语言中,一个类只需要实现了接口要求的所有函数,我们就说这个类实现了该接口。
1 | type File struct { |
Go语言可以根据下面的函数: func (a Integer) Less(b Integer) bool
自动生成一个新的Less()方法,类型*Integer就既存在Less()方法,也存在Add()方法,满足LessAdder接口
1 | type Integer int |
在Go语言中,只要两个接口拥有相同的方法列表(次序不同不要紧),那么它们就是等同的,可以相互赋值。接口赋值并不要求两个接口必须等价。如果接口A的方法列表是接口B的方法列表的子集, 么接口B可以赋值给接口A。
检查file1接口指向的对象实例是否实现了two.IStream接口,如果实现了,则执行特定的代码。接口查询是否成功,要在运行期才能够确定。它不像接口赋值,编译器只需要通过静态类型检查即可判断赋值是否可行。
1 | var file1 Writer = ... |
在Go语言中,你可以询问接口它指向的对象是否是某个类型,比如
1 | var file1 Writer = ... |
接口组合,可以认为接口组合是类型匿名组合的一个特定场景,只不过接口只包含方法,而不包含任何成员变量。
1 | // ReadWriter接口将基本的Read和Write方法组合起来 |
v1.5.2