现实世界中"重载"无处不在,"某某可以做,这里为什么不可以做"不断告诉我们,人类从来都喜欢follow一些规则,不愿意改变。函数重载不是重载的全部,运算符一样可以重载。
函数签名
- 函数名称和参数列表共同组成函数签名,函数返回值不是签名的一部分。
重载形式
- C语言不支持重载,类似的函数不得不改名。
- ObjC类成员函数支持重载。
- C++开始的面向对象语言大部分支持重载,C++ const修饰符让string类型的重载更加麻烦,程序员可能要同时处理形如
const char*
和const std::string&
类型变量,C++17引入了std::string_view, 一种只读的表示字符串的string, 不包含真实字符串数据,只有查阅的权限,简化了代码。 - C#/Java/Kotlin/仓颉 均支持重载。
- Python支持函数重载,用默认参数、可变参数和functools.singledispatch指示。
- JS没有真正的函数重载。
- Go/Rust不支持重载,Go官方给的说明是为了保持简单,这是语言设计者的意图,但事实上可能没有重载是个缺失。
类函数重载
- C++类在实现const和非const版本函数时,大部分代码都相同,但却要写2份代码。通过const_cast和as_const(C++17引入)轻松将非const版本转换成const版本。
类函数重载失效
- C++不希望某个函数特定类型参数被传入,可以显式指定废置重载。
- 例如void func(double)函数不希望传入int类型,void func(int) = delete废置int类型。
ObjC对函数重载的支持
不管是C89/C99还是C11,都不支持函数重载。ObjC遵循C标准,全局函数默认也不支持重载。但是,类成员方法名称可以加标签label, ObjC可利用label实现"重载",如下。
- - (int) add:(int)x withInt:(int)y;
- - (float) add:(float)x withFloat:(float)y;
注意,如果只有一个参数,函数名默认是第一个标签,就没办法实现重载了。