类型系统
GO中大多数类型都是值语义的,并且都可以包含对应的操作方法,而且可以在需要时给类型添加新方法。
在实现某个接口时,无需从该接口继承(事实上GO根本就不支持面向对象中的集成语法),只需实现该接口所要求的所有方法即可。
任何类型都可以被Any类型引用。Any类型就是空接口,即interface{}。
为类型添加方法
可以给任意类型添加方法
type Integer int func (a Integer) Less(b Integer) bool { return a < b } var a Integer = 1 if a.Less(2) { fmt.Println(a, "Less 2") }“在Go语言中没有隐藏的this指针”这句话的含义是:
方法施加的目标(也就是“对象”)显式传递,没有被隐藏起来;
方法施加的目标(也就是“对象”)不需要非得是指针,也不用非得叫this。
值语义和引用语义
二者差别在于:赋值b = a b.Modify()b的修改不会影响a,则是值语义,否则为引用语义
b = &a b.Modify()Go语言中的大多数类型都基于值语义,包括:
基本类型,如byte、int、bool、float32、float64和string等;
复合类型,如数组(array)、结构体(struct)和指针(pointer)等。
Go语言中有4个类型比较特别,看起来像引用类型,如下所示:
数组切片:指向数组(array)的一个区间。
map:极其常见的数据结构,提供键值查询能力。
channel:执行体(goroutine)间的通信设施。
接口(interface):对一组满足某个契约的类型的抽象
数组切片:指向数组(array)的一个区间。
map:极其常见的数据结构,提供键值查询能力。
channel:执行体(goroutine)间的通信设施。
接口(interface):对一组满足某个契约的类型的抽象
channel和map类似,本质上是一个指针
结构体
Go语言的结构体(struct)和其他语言的类(class)有同等的地位,但Go语言放弃了包括继承在内的大量面向对象特性,只保留了组合
(composition)这个最基础的特性。
type Rect struct { x, y float64 width, height float64 } //定义方法 func (r *Rect) Area() float64 { return r.width * r.height }看上去很像C吧,事实也如此,的使用方式与C语言并没有明显不同
初始化
rect1 := new(Rect) rect2 := &Rect{} rect3 := &Rect{0, 0, 100, 200} rect4 := &Rect{width: 100, height: 200}未进行显式初始化的变量都会被初始化为该类型的零值:bool ->false int->0 string ->空字符串
在Go语言中没有构造函数的概念,对象的创建通常交由一个全局的创建函数来完成,以
NewXXX来命名,表示“构造函数”:
NewXXX来命名,表示“构造函数”:
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类,继承并改写了Bar,没有改下Foo也就被继承了
在Go语言中,你还可以以指针方式从一个类型“派生”:
type Foo struct { *Base ... }关注一下接口组合中的名字冲突问题
type X struct { Name string } type Y struct { X Name string }如上例,Y类型中有有成员Name,其匿名组合X中也有同名的Name,但所有Y类型访问成员Name都只能访问到外层的,X类中的Name被隐藏了
再看:
type Logger struct { Level int } type Y struct { *Logger Name string *log.Logger }如上就不行了,匿名组合,可以认为是用其类型名称(去掉包名部分)作为成员变量的名字,这里就会有两个同名的 Logger。那是不可以
有疑问加站长微信联系(非本文作者)