Golang中没有设计构造函数. 取而代之的, 设计Golang的大师希望你用普通函数去实现构造的任务.
一直只是觉得这只是体现Golang这门新语言的精简设计之道, 直到自己实现编译器后才发现构造函数的设计本身是值得商榷的
我们先看下构造函数的规则
构造函数调用规则
构造参数量: 0表示没有构造函数, 1表示有构造函数0个参数
本类构造 | 父类构造 | 处理方法 |
---|
0 | 0 | 不处理 |
1 | 0 | 调本类ctor |
0 | 1 | 调父类ctor |
1 | 1 | 调本类ctor, 本类ctor调父类ctor |
2 | 1 | 调本类ctor, 本类ctor调父类ctor |
1 | 2 | 报错, 手动调父类ctor |
2 | 2 | 报错, 手动调父类ctor |
普通函数重载规则
实际只用考虑最典型的一种行为: 实例化子类, 转为父类调用方法, 这个时候
如果方法是override, 调用的是子类
如果方法是virutal或者不指明, 调用的是父类
整个重载过程, 子类绝对不会隐式调用父类的行为
需要构造函数么?
构造函数的优点
- 本身属于一种特殊的成员函数
- 编译器帮你自动传导调用父级
构造函数的缺点
- 隐式的调用规则
- 虽然属于成员函数, 但是与其他成员函数调用规则完全不同, 需要特殊记忆
- 带参数的构造函数, 在父类参数多于子类时, 需要引用复杂语法来实现父级构造调用
其实我们对初始化函数的需求只有1条: 自定义
所以, 可以理解Golang不加入构造函数的设计是正确的
即: 简单, 清晰, 有规律