学编程,最烦的莫过于看到一大堆新术语,以及看到分不清的术语,这里说的“签名”和“接口”就是经常被混淆使用的。乱用术语害人害己,所以这里区分一下两者。
用人话简单概况一下,就是:签名给计算机看,接口给人看。
一. “签名”是什么意思?——例:真假唐龙
其实,我觉得“名片”更适合这个概念。我们先从例子开始,之后再不说人话。
两只唐龙相遇了,它们争吵谁才是真正的唐王。它们的证明过程就是表明身份的过程:
名字 | 奶龙 |
---|---|
技能1 | 喷火 |
技能2 | 变色 |
技能3 | 啥都吃 |
两个唐王(技能3是小七认为)都认为,作为唐龙需要满足这些条件,满足这些条件的就是唐龙。这些条件表明了唐龙的身份,用来判断一个对象是不是我们要找的唐龙。这就是“名片”或“签名”的作用——用于唯一标识对象。
当然,“原著”里两者难分伯仲,不过函数签名的精确度足以唯一标识对象。对于唐龙的问题,我们在掌握足够的信息后其实也能区分,例如:
名字 | 奶龙 | 奶浓 |
技能1 | 喷火 | 喷火 |
技能2 | 变色 | 变色 |
技能3 | 啥都吃 | 啥都吃 |
归属 | 小七 | 大唐王朝 |
因为小七只有一只奶龙,另外一只就不是小七的。如果我们查看了“奶龙”这一对象的“归属”标志,就能轻松将两者区分开。什么……做不到么?幸好我们不是小七,是程序员呀!函数的标志绝对更容易查看啦。
好了,我要不说人话了:
函数的签名是用于唯一标识函数的语法特征,通常包括:函数名,参数类型及顺序(参数数量、类型、修饰符,如 const),所属作用域(如类的命名空间)。它的作用基本上是:供编译器/解释器区分函数重载;决定函数在符号表中的唯一标识。
下面是C++的例子,请注意:Python是动态语言,没有严格的函数签名,因此不支持同一作用域内的同名函数——后定义的函数会覆盖先定义的函数。
所以我不能举Python的例子了,不爽(*  ̄︿ ̄)。
//两个不同签名的函数
void print(int x) {
std::cout << "Integer: " << x << std::endl;
}
// 签名:print(int)->void
void print(double x) {
std::cout << "Double: " << x << std::endl;
}
// 签名:print(double)->void
这两个print函数的签名表明,它们都没有返回值(是void,虚无),参数分别是整数(int)及双精度浮点数(double)。当你调用print时,C++会根据签名来找到相应的唯一print函数,这里只要知道传入参数的类型——不会有歧义:
print(5); // 调用 void print(int)
print(5.0); // 调用 void print(double)
二. “接口”是什么意思?——例:呆傻充电宝
感觉这个名称起的好多了,请想象一下充电宝,外表“呆傻”的它的结构像下面这样复杂:
充电宝,作为一种便携式电源设备,主要用于给手机等电子设备充电。其内部结构主要包括以下几个关键部分:
外壳:通常由塑料或金属制成,具有保护内部组件的作用,并且在一定程度上还能散热。
电池芯:这是充电宝的核心部件,通常采用锂离子电池或锂聚合物电池。这些电池芯决定了充电宝的容量(mAh)和输出能力。根据型号的不同,可能包含一个或多个电池单元。
电路板(PCB):包括充电管理电路和放电管理电路,负责控制电池的充电过程、防止过充、过放以及提供稳定的输出电压。此外,还集成了温度控制、短路保护等功能,确保使用安全。
输入接口:通常是Micro USB、USB-C等类型,用于连接外部电源为充电宝自身充电。
输出接口:一般是标准的USB接口,有的新款充电宝也会配备USB-C PD(Power Delivery)接口,可以支持更快的充电速度。
开关/按钮:一些充电宝配备了物理开关或按钮,用于开启或关闭设备,有些还可以用来显示电量状态。
LED指示灯:用于显示充电宝当前的电量状态和充电状态。通常有几颗LED灯来表示电量等级。……
想必你看到这,心里最大的想法就是:师傅别念了!
我又不是专业人士,你给我解释这干嘛?我只想知道充电宝怎么用而已啊!这就对了,我们作为程序员,大部分时间不是自己发明轮子,而是使用别人的轮子——我们不关心内部实现细节,只想知道这个工具该怎么用,接口就是用来说明它该怎么用的。我把数据线一端接上充电宝的接口,就可以充电了,世界如此简单!
下面我又要开始不说人话了:
函数的接口是开发者调用函数时需要了解的约定,函数的接口包括:函数名,参数含义(名称、类型、默认值、是否可选),返回值类型及语义,异常行为(可能抛出的异常类型),副作用(如是否修改全局状态)。它的作用基本上是:定义函数的使用方式;隐藏实现细节,强调功能和行为契约。
例如,下面是我为一个Python装饰器写的接口说明(这个装饰器的代码可以在我其它文章中找到,感兴趣的话可以去看看):
有了这段说明,要使用它就不必去看代码细节, 当然前提是说明得是正确的。
三. 对比&总结一下
特性 | 函数签名 | 函数接口 |
侧重点 | 语法唯一性(编译器/链接器) | 功能契约(开发者) |
包含内容 | 函数名、参数类型、顺序、作用域 | 函数名、参数语义、返回值、异常、副作用 |
语言相关性 | 严格依赖语言规范(如C++、Java) | 通用设计概念(所有语言) |
重载决定因素 | 是 | 否 |
运行时影响 | 无(编译时概念) | 有(影响程序逻辑和健壮性) |
赛后总结:
-
函数签名是编译器/解释器的语法标识,解决“如何区分函数”的问题。
-
函数接口是开发者间的功能契约,解决“如何正确使用函数”的问题。
-
可以说签名是接口的语法部分,因为接口(可能)在语法外还包含更丰富的语义信息。
我们就谈到这里吧!大家写代码时一定要注意身体啊,头痛欲裂真的很难受QAQ