从事Windows下C/C++编程的人很可能遇到过类似nCount
、stPerson
这类风格的命名,这类风格的命名方式即为匈牙利命名法。
匈牙利命名法起源
匈牙利命名法(HungarianNotation)是由匈牙利裔美国人Charles Simony发明的,由于其单词排列顺序类似古怪的匈牙利姓名而得名。
实际上Charles Simony发明的是应用型匈牙利命名法,由于被曲解、以讹传讹,形成了我们常见的系统型匈牙利命名法。文章开头的两个例子的风格来自于系统型匈牙利命名法。
这段历史在Joel on Software
的《讓錯的程式看得出錯》有详细的介绍。
匈牙利命名法的构造
应用型匈牙利命名法和系统型匈牙利命名法都是通过前缀+对象描述
的形式命名。
- 应用型匈牙利命名法
前缀体现自然语义,主要是说明变量的应用属性或业务属性,抽象层次较高,如:若 Fahrenheit简称为
fah
,Celsius 简称为cel
。下面的代码我们一眼就能看出问题:int fahTemp = celThermometer;
因为华氏温度和摄氏温度肯定不能直接赋值,它们之间有转换关系,所以代码逻辑错误。 - 系统型匈牙利命名法
而匈牙利系统命名法的前缀是为了说明变量的系统属性,最常用的是变量类型,上面的例子改写为:int iTemp = iThermometer;
i
标识变量类型是int
,我们很难看出其中的问题。
系统型匈牙利命名法的缺点
Windows开发的圣经《Windows 程序设计》第一版大量使用了匈牙利命名法,所以系统型匈牙利命名法是Windows开发的事实标准。但随后的反对也愈演愈烈,在.net第一次发布时达到了高潮。微软在.net框架的《通用命名约定》中明确说明不建议使用匈牙利命名法。到现在,除了一些遗产代码,新的代码已经鲜见系统型匈牙利命名法了,而且《Windows 程序设计》第六版也不怎么使用匈牙利命名法了。
我认为其的几个缺点:
- IDE流行,特殊标注类型已没有必要
有图有真相:
图中是Rust的代码段,guess
后面的String
是IDE推断出的,现代的工具已经很发达,能有效避免这种纯手工的标注。
其他语言同理。
- 抽象层次低,对问题排查没有用处
类型不一致导致的问题,在大多数语言的编译器都会产生错误或警告,人工做编译器的工作,没有必要。如果出错,大部分错误都是逻辑错误,这种类型标注帮不了什么忙。
- 适用面窄,跟不上发展
该命名法对于C++引入模板容器来说就是灾难。引入的容器、迭代器等等很多,单字母已经无法表示,姑且用vec
表示std::vector
,那该模板类的实例std::vector<int>
怎么表示?
即使能表示,std::vector<std::vector<std::vector<int>>>
这个又怎么表示?
世上没有解决不了的问题,上述的问题肯定也是可以解决的,只要制定相应的规则即可。问题是:这个成本能得到多大的回报。对于系统匈牙利命名法来说,是没有必要的。
请关注我的公众号哦。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。