编程5分钟,命名2小时!聊聊命名规则!

C语言与CPP编程 2021-09-29 08:47

软件中随处可见命名:要给变量、函数、参数、类和封包命名,还要给源代码及源代码所在目录命名,甚至还有jar文件、war文件和ear文件命名。


但是,看似简单的命名,也是让不少程序员头疼的问题。有一些小伙伴,在进行变量命名的时候,对于自己熟悉的英文,可能还会用英文命名一下,如果需要命名的部分不会用英文表达,或许就直接用拼音了。


有的童鞋一下想不起来怎么命名,直接用拼音直接用aa,bb等这样没有任何代表意义的字母来命名,可读性非常差,可能自己今天写的,一个星期后回来再看,也忘记其具体代表的含义了。


因此,许多人在写代码之前,总会在想啊想啊,用什么命名法好呢?对于经常在C++、Java、Python等主流语言上切换的强迫症来说,换个语言换种命名风格简直不要太混乱。


既然有这么多命名要做,不妨做好它。本期内容中,异步君为大家带来了起个好名字应遵从的几条简单规则,一起来看看吧


01

名副其实



名副其实说起来简单。我们想要强调,这事很严肃。选个好名字要花时间,但省下来的时间比花掉的多。注意命名,而且一旦发现有更好的名称,就换掉旧的。这么做,读你代码的人(包括你自己)都会更开心。


变量、函数或类的名称应该已经答复了所有的大问题。它该告诉你,它为什么会存在,它做什么事,应该怎么用。如果名称需要注释来补充,那就不算是名副其实。

int d;  // elapsed time in days


名称d什么也没说明。它没有引起读者对时间消逝的感觉,更别说以日计了。我们应该选择指明了计量对象和计量单位的名称:

int elapsedTimeInDays;int daysSinceCreation;int daysSinceModification;int fileAgeInDays;


选择体现本意的名称能让人更容易理解和修改代码。下列代码的目的何在?

public List<int[]> getThem() {  List<int[]> list1 = new ArrayList<int[]>();  for (int[] x : theList)    if (x[0] == 4)      list1.add(x);  return list1;}


为什么难以说明上述代码要做什么事?里面并没有复杂的表达式,空格和缩进中规中矩,只用到三个变量和两个常量,甚至没有涉及任何其他类或多态方法,只是(或者看起来是)一个数组的列表而已。


问题不在于代码的简洁度,而在于代码的模糊度:即上下文在代码中未被明确体现的程度。上述代码要求我们了解类似以下问题的答案:

(1)theList中是什么类型的东西?

(2)theList零下标条目的意义是什么?

(3)值4的意义是什么?

(4)我怎么使用返回的列表?


问题的答案没体现在代码段中,可代码段就是它们该在的地方。比方说,我们在开发一种扫雷游戏,我们发现,盘面是名为theList的单元格列表,那就将其名称改为gameBoard。


盘面上每个单元格都用一个简单数组表示。我们还发现,零下标条目是一种状态值,而该种状态值为4表示“已标记”。只要改为有意义的名称,代码就会得到相当程度的改进:

public List<int[]> getFlaggedCells()  {  List<int[]> flaggedCells = new ArrayList<int[]>();  for (int[] cell : gameBoard)    if (cell[STATUS_VALUE] == FLAGGED)      flaggedCells.add(cell);  return flaggedCells;}


注意,代码的简洁性并未被触及。运算符和常量的数量全然保持不变,嵌套数量也全然保持不变,但代码变得明确多了。


还可以更进一步,不用int数组表示单元格,而是另写一个类。该类包括一个名副其实的函数(称为isFlagged),从而掩盖住那个魔术数[1]。于是得到函数的新版本:

public List<Cell> getFlaggedCells()  {  List<Cell> flaggedCells = new ArrayList<Cell>();  for (Cell cell : gameBoard)    if (cell.isFlagged())      flaggedCells.add(cell);  return flaggedCells;}


只要简单改一下名称,就能轻易知道发生了什么。这就是选用好名称的力量。


02

避免误导



程序员必须避免留下掩藏代码本意的错误线索。应当避免使用与本意相悖的词,例如,hp、aix和sco都不该用作变量名,因为它们都是Unix平台或类Unix平台的专有名称。即便你是在编写三角计算程序,hp看起来是一个不错的缩写[2],但那也可能会提供错误信息。


别用accountList来指称一组账号,除非它真的是List类型。List一词对程序员有特殊意义。如果包纳账号的容器并非真是一个List,就会引起错误的判断。


所以,用accountGroup或bunchOfAccounts,甚至直接用accounts都会好一些。


提防使用外形相似度较高的名称。例如,想区分模块中某处的XYZControllerFor-EfficientHandlingOfStrings和另一处的XYZControllerForEfficientStorage-OfStrings,会花多长时间呢?这两个词的外形实在太相似了。


以同样的方式拼写出同样的概念才是信息。拼写前后不一致就是误导。我们很享受现代Java编程环境的自动代码完成特性。键入某个名称的前几个字母,按一下某个热键组合(如果有的话),就能得到一列该名称的可能形式。


假如相似的名称依字母顺序放在一起,且差异很明显,那就会相当有助益,因为程序员多半会压根不看你的详细注释,甚至不看该类的方法列表就直接看名字挑一个对象。


误导性名称真正可怕的例子,是用小写字母l和大写字母O作为变量名,尤其是在组合使用的时候。当然,问题在于它们看起来完全像是常量“壹”和“零”。

int a = l;if (O == l)  a = O1;else  l = 01;


读者可能会认为这纯属虚构,但我们确曾见过充斥这类名称的代码。有一次,代码作者建议用不同字体写变量名,好显得更清楚些,但前提是这种方案得要通过口头和书面传递给未来所有的开发者才行。后来,只是做了简单的重命名操作,就解决了问题,而且也没引起别的问题。


03

做有意义的区分



如果程序员只是为满足编译器或解释器的需要而写代码,就会制造麻烦。例如,因为同一作用范围内两样不同的东西不能重名,你可能会随手改掉其中一个的名称,有时干脆以错误的拼写充数,结果就会出现在更正拼写错误后导致编译器出错的情况。


光是添加数字系列或是废话远远不够,即便这足以让编译器满意。如果名称必须相异,那么其意思也应该不同才对。


以数字系列命名(a1、a2…aN)是依义命名的对立面。这样的名称纯属误导——完全没有提供正确信息,没有提供导向作者意图的线索。试看:

public static void copyChars(char a1[], char a2[]) {  for (int i = 0; i < a1.length; i++) {    a2[i] = a1[i];  }}


如果参数名改为source和destination,这个函数就会像样许多。


废话是另一种没意义的区分。假设你有一个Product类,如果还有一个名为ProductInfo或ProductData的类,那它们的名称虽然不同,意思却无区别。Info和Data就像a、an和the一样,是意义含混的废话。


注意,只要体现出有意义的区分,使用a和the这样的前缀就没错。例如,你可能把a用在域内变量,而把the用于函数参数[5]。但如果你已经有一个名为zork的变量,又想调用一个名为theZork的变量,麻烦就来了。


废话都是冗余。variable一词永远不应当出现在变量名中。table一词永远不应当出现在表名中。NameString会比Name好吗?难道Name会是一个浮点数?如果是这样,就违反了关于误导的规则。

设想有一个名为Customer的类,还有一个名为CustomerObject的类,它们的区别何在呢?哪一个是表示客户历史支付情况的最佳方式?


有一个应用反映了这种状况。为当事者讳,我们改了一下,不过犯错的代码的确就是这个样子:


getActiveAccount(); getActiveAccounts(); getActiveAccountInfo();

程序员怎么知道该调用哪个函数呢?


如果缺少明确约定,那么变量moneyAmount与money就没区别,customerInfo与customer没区别,accountData与account没区别,theMessage也与message没区别。要区分名称,就要以读者能鉴别不同之处的方式来区分。


04

使用读得出来的名称



人类长于记忆和使用单词。大脑的相当一部分就是用来容纳和处理单词的。单词能读得出来。人类的大脑中有那么大的一块地方用来处理言语,若不善加利用,实在是种耻辱。


如果名称读不出来,讨论的时候就会像个傻鸟。“哎,这儿,鼻涕阿三喜摁踢(bee cee arr three cee enn tee)[6]上头,有个皮挨死极翘(pee ess zee kyew)[7]整数,看见没?”这不是小事,因为编程本就是一种社会活动。


有一家公司,程序里面写了一个genymdhms(生成日期,年、月、日、时、分、秒),他们一般读作“gen why emm dee aich emm ess”[8]。我有见字照拼读的恶习,于是开口就念“gen-yah-mudda-hims”。


后来好些设计师和分析师都有样学样,听起来傻乎乎的。我们知道典故,所以会觉得很搞笑。搞笑归搞笑,实际是在强忍糟糕的命名。在给新开发者解释变量名的意义时,他们总是读出傻乎乎的自造词,而非恰当的英语词。比较

class DtaRcrd102 {  private Date genymdhms;  private Date modymdhms;  private final String pszqint = "102";  /*  ...  */};
class Customer { private Date generationTimestamp; private Date modificationTimestamp; private final String recordId = "102"; /* ... */};


现在读起来就像人话了:“喂,Mikey,看看这条记录!生成时间戳(generation timestamp)[9]被设置为明天了!不能这样吧?”


05

使用可搜索的名称



对于单字母名称和数字常量,有一个问题,就是很难在一大篇文字中找出来。


找MAX_CLASSES_PER_STUDENT很容易,但想找数字7就麻烦了,它可能是某些文件名或其他常量定义的一部分,出现在因不同意图而采用的各种表达式中。如果该常量是个长数字,又被人错改过,就会逃过搜索,从而造成错误。


同样,e也不是一个便于搜索的好变量名,它是英文中最常用的字母,在每个程序、每段代码中都有可能出现。由此而见,长名称胜于短名称,搜得到的名称胜于用自造编码代写就的名称。


窃以为单字母名称仅用于短方法中的本地变量。名称长短应与其作用域大小相对应 [N5]。若变量或常量可能在代码中多处使用,则应赋予其便于搜索的名称。再比较:

for (int j=0; j<34; j++) {  s += (t[j]*4)/5;}
int realDaysPerIdealDay = 4;const int WORK_DAYS_PER_WEEK = 5;int sum = 0;for (int j=0; j < NUMBER_OF_TASKS; j++) { int realTaskDays = taskEstimate[j] * realDaysPerIdealDay; int realTaskWeeks = (realTaskdays / WORK_DAYS_PER_WEEK); sum += realTaskWeeks;}


注意,上面代码中的sum并非特别有用的名称,不过至少搜得到它。采用能表达意图的名称,貌似拉长了函数代码,但要想想看,WORK_DAYS_PER_WEEK比数字5好找得多,而列表中也只剩下了体现作者意图的名称。


06

避免使用编码



编码已经太多,无谓再自找麻烦。把类型或作用域编进名称里面,徒然增加了解码的负担。没理由要求每位新人都在弄清要应付的代码之外(那算是正常的),还要再搞懂另一种编码“语言”。这对解决问题而言,纯属多余的负担。带编码的名称通常也不便发音,容易打错。


匈牙利语标记法


在往昔名称长短很重要的时代,我们毫无必要地破坏了不编码的规矩,如今后悔不迭。Fortran语言要求首字母体现出类型,导致了编码的产生。BASIC语言的早期版本只允许使用一个字母再加上一位数字。匈牙利语标记法[10](Hungarian Notation,HN)将这种态势愈演愈烈。


在Windows的C语言API的时代,HN相当重要,那时所有名称要么是一个整数句柄,要么是一个长指针或者void指针,要不然就是string的几种实现(有不同的用途和属性)之一。那时候编译器并不做类型检查,程序员需要匈牙利语标记法来帮助自己记住类型。


现代编程语言具有更丰富的类型系统,编译器也记得并强制使用类型。而且,程序员趋向于使用更小的类、更短的方法,好让每个变量的定义都在视野范围之内。


Java程序员不需要类型编码,因为对象是强类型的,代码编辑环境已经先进到在编译开始前就能监测到类型错误的程度!所以,如今HN和其他的类型编码形式都纯属多余。它们增加了修改变量、函数或类的名称或类型的难度,它们增加了阅读代码的难度,它们制造了让编码系统误导读者的可能性。

PhoneNumber  phoneString;//  name not changed when type changed!


成员前缀


也不必用m_前缀来标明成员变量。应当把类和函数做得足够小,以消除对成员前缀的需要。你应当使用某种可以高亮或用颜色标出成员的编辑环境。

public class Part {  private String m_dsc; // The textual description  void setName(String name) {    m_dsc = name;  }}--------------------------------------------------------------------------------------public class Part {  String description;  void setDescription(String description) {    this.description = description;  }}


此外,人们会很快学会无视前缀(或后缀),而只看到名称中有意义的部分。代码读得越多,眼中就越没有前缀。最终,前缀变作了不入法眼的废料,变作了旧代码的标志物。


接口和实现


有时也会出现采用编码的特殊情形。比如,你在做一个创建形状用的抽象工厂(Abstract Factory),该工厂是一个接口,要用具体类来实现。你怎么来命名工厂和具体类呢?IShapeFactory和ShapeFactory吗?我喜欢不加修饰的接口。前导字母I被滥用到了说好听点儿是干扰,说难听点儿根本就是废话的程度。


我不想让用户知道我给他们的是接口,而就想让他们知道那是一个ShapeFactory。如果在接口和实现中必须选其一来编码的话,我宁肯选择实现。ShapeFactoryImp,甚至是丑陋的CShapeFactory,都比对接口名称编码好。

C语言与CPP编程 C语言/C++开发,C语言/C++基础知识,C语言/C++学习路线,C语言/C++进阶,数据结构;算法;python;计算机基础等
评论 (0)
  • 在智能硬件设备趋向微型化的背景下,语音芯片方案厂商针对小体积设备开发了多款超小型语音芯片方案,其中WTV系列和WT2003H系列凭借其QFN封装设计、高性能与高集成度,成为微型设备语音方案的理想选择。以下从封装特性、功能优势及典型应用场景三个方面进行详细介绍。一、超小体积封装:QFN技术的核心优势WTV系列与WT2003H系列均提供QFN封装(如QFN32,尺寸为4×4mm),这种封装形式具有以下特点:体积紧凑:QFN封装通过减少引脚间距和优化内部结构,显著缩小芯片体积,适用于智能门铃、穿戴设备
    广州唯创电子 2025-04-30 09:02 242浏览
  • 一、智能家居的痛点与创新机遇随着城市化进程加速,现代家庭正面临两大核心挑战:情感陪伴缺失:超60%的双职工家庭存在“亲子陪伴真空期”,儿童独自居家场景增加;操作复杂度攀升:智能设备功能迭代导致用户学习成本陡增,超40%用户因操作困难放弃高阶功能。而WTR096-16S录音语音芯片方案,通过“语音交互+智能录音”双核驱动,不仅解决设备易用性问题,更构建起家庭成员间的全天候情感纽带。二、WTR096-16S方案的核心技术突破1. 高保真语音交互系统动态情绪语音库:支持8种语气模板(温柔提醒/紧急告警
    广州唯创电子 2025-04-28 09:24 191浏览
  • 浪潮之上:智能时代的觉醒    近日参加了一场课题的答辩,这是医疗人工智能揭榜挂帅的国家项目的地区考场,参与者众多,围绕着医疗健康的主题,八仙过海各显神通,百花齐放。   中国大地正在发生着激动人心的场景:深圳前海深港人工智能算力中心高速运转的液冷服务器,武汉马路上自动驾驶出租车穿行的智慧道路,机器人参与北京的马拉松竞赛。从中央到地方,人工智能相关政策和消息如雨后春笋般不断出台,数字中国的建设图景正在智能浪潮中徐徐展开,战略布局如同围棋
    广州铁金刚 2025-04-30 15:24 193浏览
  • 4月22日下午,备受瞩目的飞凌嵌入式「2025嵌入式及边缘AI技术论坛」在深圳深铁皇冠假日酒店盛大举行,此次活动邀请到了200余位嵌入式技术领域的技术专家、企业代表和工程师用户,共享嵌入式及边缘AI技术的盛宴!1、精彩纷呈的展区产品及方案展区是本场活动的第一场重头戏,从硬件产品到软件系统,从企业级应用到高校教学应用,都吸引了现场来宾的驻足观看和交流讨论。全产品矩阵展区展示了飞凌嵌入式丰富的产品线,从嵌入式板卡到工控机,从进口芯片平台到全国产平台,无不体现出飞凌嵌入式在嵌入式主控设备研发设计方面的
    飞凌嵌入式 2025-04-28 14:43 157浏览
  •  探针台的维护直接影响其测试精度与使用寿命,需结合日常清洁、环境控制、定期校准等多维度操作,具体方法如下:一、日常清洁与保养1.‌表面清洁‌l 使用无尘布或软布擦拭探针台表面,避免残留清洁剂或硬物划伤精密部件。l 探针头清洁需用非腐蚀性溶剂(如异丙醇)擦拭,检查是否弯曲或损坏。2.‌光部件维护‌l 镜头、观察窗等光学部件用镜头纸蘸取wu水jiu精从中心向外轻擦,操作时远离火源并保持通风。3.‌内部防尘‌l 使用后及时吹扫灰尘,防止污染物进入机械滑
    锦正茂科技 2025-04-28 11:45 111浏览
  • 网约车,真的“饱和”了?近日,网约车市场的 “饱和” 话题再度引发热议。多地陆续发布网约车风险预警,提醒从业者谨慎入局,这背后究竟隐藏着怎样的市场现状呢?从数据来看,网约车市场的“过剩”现象已愈发明显。以东莞为例,截至2024年12月底,全市网约车数量超过5.77万辆,考取网约车驾驶员证的人数更是超过13.48万人。随着司机数量的不断攀升,订单量却未能同步增长,导致单车日均接单量和营收双双下降。2024年下半年,东莞网约出租车单车日均订单量约10.5单,而单车日均营收也不容乐
    用户1742991715177 2025-04-29 18:28 225浏览
  • 贞光科技代理品牌紫光国芯的车规级LPDDR4内存正成为智能驾驶舱的核心选择。在汽车电子国产化浪潮中,其产品以宽温域稳定工作能力、优异电磁兼容性和超长使用寿命赢得市场认可。紫光国芯不仅确保供应链安全可控,还提供专业本地技术支持。面向未来,紫光国芯正研发LPDDR5车规级产品,将以更高带宽、更低功耗支持汽车智能化发展。随着智能网联汽车的迅猛发展,智能驾驶舱作为人机交互的核心载体,对处理器和存储器的性能与可靠性提出了更高要求。在汽车电子国产化浪潮中,贞光科技代理品牌紫光国芯的车规级LPDDR4内存凭借
    贞光科技 2025-04-28 16:52 260浏览
  • 文/Leon编辑/cc孙聪颖‍2023年,厨电行业在相对平稳的市场环境中迎来温和复苏,看似为行业增长积蓄势能。带着对市场向好的预期,2024 年初,老板电器副董事长兼总经理任富佳为企业定下双位数增长目标。然而现实与预期相悖,过去一年,这家老牌厨电企业不仅未能达成业绩目标,曾提出的“三年再造一个老板电器”愿景,也因市场下行压力面临落空风险。作为“企二代”管理者,任富佳在掌舵企业穿越市场周期的过程中,正面临着前所未有的挑战。4月29日,老板电器(002508.SZ)发布了2024年年度报告及2025
    华尔街科技眼 2025-04-30 12:40 210浏览
  • 你是不是也有在公共场合被偷看手机或笔电的经验呢?科技时代下,不少现代人的各式机密数据都在手机、平板或是笔电等可携式的3C产品上处理,若是经常性地需要在公共场合使用,不管是工作上的机密文件,或是重要的个人信息等,民众都有防窃防盗意识,为了避免他人窥探内容,都会选择使用「防窥保护贴片」,以防止数据外泄。现今市面上「防窥保护贴」、「防窥片」、「屏幕防窥膜」等产品就是这种目的下产物 (以下简称防窥片)!防窥片功能与常见问题解析首先,防窥片最主要的功能就是用来防止他人窥视屏幕上的隐私信息,它是利用百叶窗的
    百佳泰测试实验室 2025-04-30 13:28 331浏览
  • 随着电子元器件的快速发展,导致各种常见的贴片电阻元器件也越来越小,给我们分辨也就变得越来越难,下面就由smt贴片加工厂_安徽英特丽就来告诉大家如何分辨的SMT贴片元器件。先来看看贴片电感和贴片电容的区分:(1)看颜色(黑色)——一般黑色都是贴片电感。贴片电容只有勇于精密设备中的贴片钽电容才是黑色的,其他普通贴片电容基本都不是黑色的。(2)看型号标码——贴片电感以L开头,贴片电容以C开头。从外形是圆形初步判断应为电感,测量两端电阻为零点几欧,则为电感。(3)检测——贴片电感一般阻值小,更没有“充放
    贴片加工小安 2025-04-29 14:59 228浏览
  • 一、gao效冷却与控温机制‌1、‌冷媒流动设计‌采用低压液氮(或液氦)通过毛细管路导入蒸发器,蒸汽喷射至样品腔实现快速冷却,冷却效率高(室温至80K约20分钟,至4.2K约30分钟)。通过控温仪动态调节蒸发器加热功率,结合温度传感器(如PT100铂电阻或Cernox磁场不敏感传感器),实现±0.01K的高精度温度稳定性。2、‌宽温区覆盖与扩展性‌标准温区为80K-325K,通过降压选件可将下限延伸至65K(液氮模式)或4K(液氦模式)。可选配475K高温模块,满足材料在ji端温度下的性能测试需求
    锦正茂科技 2025-04-30 13:08 259浏览
  • 文/郭楚妤编辑/cc孙聪颖‍越来越多的企业开始蚕食动力电池市场,行业“去宁王化”态势逐渐明显。随着这种趋势的加强,打开新的市场对于宁德时代而言至关重要。“我们不希望被定义为电池的制造者,而是希望把自己称作新能源产业的开拓者。”4月21日,在宁德时代举行的“超级科技日”发布会上,宁德时代掌门人曾毓群如是说。随着宁德时代核心新品骁遥双核电池的发布,其搭载的“电电增程”技术也走进业界视野。除此之外,经过近3年试水,宁德时代在换电业务上重资加码。曾毓群认为换电是一个重资产、高投入、长周期的产业,涉及的利
    华尔街科技眼 2025-04-28 21:55 169浏览
  • 在CAN总线分析软件领域,当CANoe不再是唯一选择时,虹科PCAN-Explorer 6软件成为了一个有竞争力的解决方案。在现代工业控制和汽车领域,CAN总线分析软件的重要性不言而喻。随着技术的进步和市场需求的多样化,单一的解决方案已无法满足所有用户的需求。正是在这样的背景下,虹科PCAN-Explorer 6软件以其独特的模块化设计和灵活的功能扩展,为CAN总线分析领域带来了新的选择和可能性。本文将深入探讨虹科PCAN-Explorer 6软件如何以其创新的模块化插件策略,提供定制化的功能选
    虹科汽车智能互联 2025-04-28 16:00 184浏览
  • 晶振在使用过程中可能会受到污染,导致性能下降。可是污染物是怎么进入晶振内部的?如何检测晶振内部污染物?我可不可以使用超声波清洗?今天KOAN凯擎小妹将逐一解答。1. 污染物来源a. 制造过程:生产环境不洁净或封装密封不严,可能导致灰尘和杂质进入晶振。b. 使用环境:高湿度、温度变化、化学物质和机械应力可能导致污染物渗入。c. 储存不当:不良的储存环境和不合适的包装材料可能引发化学物质迁移。建议储存湿度维持相对湿度在30%至75%的范围内,有助于避免湿度对晶振的不利影响。避免雨淋或阳光直射。d.
    koan-xtal 2025-04-28 06:11 149浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦