短标识符不好吗?[关闭]


26

短标识符不好吗?标识符长度与代码理解如何相关?在命名标识符时,还需要考虑哪些其他因素(除了代码理解能力之外)?

只是为了保持答案的质量,请注意,已经对该主题进行了一些研究!

编辑

奇怪的是,当我提供的两个链接都表明大标识符有害时,每个人都认为长度不相关或倾向于使用更大的标识符!

断链

下面的链接指向对该主题的研究,但现在已断开,我似乎没有与该文件的复印件,而且我不记得它是什么。我把它留在这里,以防别人弄清楚。


5
数据点。我最喜欢的短标识符是:,例如:(){ :;:& };:-我会说大多数人认为它很糟糕。;)

@fennec:叉子炸弹往往是。
乔什·K

检查一下stackoverflow问题,有一个关于“编程实践”的评论每个程序员都应该读这本书。
slu 2010年

1
仅仅因为应避免使用较长的名称,并不表示您应该为了简短起见而将其缩短。
JeffO 2011年

1
@cessor有趣的是,原本打算与研究相关的某些事情已基于观点被关闭。令人遗憾的是,我同意了它给出的答案。
Daniel C. Sobral '18

Answers:


67

我听到的最好的“规则”是名称长度应与变量范围的长度成比例。因此,i如果循环的主体长几行,则索引就可以了,但是如果长度超过15行,我希望使用更具描述性的内容。


6
我从未听说过这样的事情,并且我认为该原则不会提高代码的可读性。
NimChimpsky 2010年

8
@Nim:我同意。即使是短暂的for循环,我也要为索引命名customerCounter。它花费最少的精力,并使您的代码变得更好。在短范围内使用短变量听起来像是懒惰的借口。
没人2010年

2
嗯,这不是我的规则或准则,而是一种让您思考长度的方法,在这种情况下,这是有意义的。我当然不认为这是懒惰的借口(尽管我会同意有些人可能会这样认为)。我的标识符经常会出现(不是很早就教过Pascal的迹象),除非现在当我遇到诸如linq查询和lambda表达式之类的东西时,其中1、2或3个字符标识符(通常是类型首字母)对我来说很有意义。
Murph

33
+1老实说,“描述性”名称只是五行循环中的噪音;我认为大多数人都非常了解您使用“ i”所做的事情。我在嵌套循环中使用了描述性名称,但它们的作用域更长。
杰里米(Jeremy)2010年

18
+1-使用ij是每个开发人员都应该能够理解IMO的通用名称
TheCloudlessSky 2010年

48

每个变量都应具有含义,并且其名称是该含义的一部分。这是非常重要的部分,因为它可以帮助读者了解其用途,而无需深入研究算法。ij明显被用作指标,他们短,但内容非常丰富。bnt是丑陋的close还是closeButton有意义的 因此,变长还是变长不是变量名的最重要标准,这应该是有意义的。意义在很大程度上取决于上下文。例如,您可以给n本地字符串变量起一个非常短的名称,该变量用于一小段代码(例如10行)中,并指向属性的名称(v例如value)。

所以变量名应该是信息性的,短和长都没关系


2
+1,只是要注意,close和closeButton也不是同义词。Close是一个动词,因此应该是函数或方法的名称。尽管closeButton是一个名词,并且显然应该是触发关闭功能的按钮的名称。
CaffGeek 2010年

关闭是一个形容词,例如close = true;)
Armand 2010年

13

我将使用一个描述变量的标识符,而不考虑其长度。

的情况下,I,J和K,本身就是无处不他们是自我描述,你会自动知道他们是循环指数。您也可以针对以下内容说同样的话:

foreach loop (Strings s : myString)

但是,IDE现在提供了代码完成工具,因此afaik消除了非常长且具有描述性的标识符的唯一负面影响。

如果需要解释变量的目的,我会很乐意在标识符中添加多余的单词。


3
顺便说一句,将i,j和k用于循环索引可以追溯到50年前FORTRAN。以字母I到N开头的变量默认情况下为INTEGER类型。默认情况下,以其他字母开头的变量为REAL。这自然导致使用I,J和K进行for循环索引。(FORTRAN约定可能来自
于此

2
我链接的第二篇论文表明,很长的描述性标识符降低了人们理解代码的能力,与“唯一的负面影响”这一说法相矛盾。
Daniel C. Sobral

3
较长标识符的真正负面影响在于可读性。很难一眼就知道两个很长的标识符是相同还是不同,并且很难挑出具有很长的标识符的表达式的所有元素。
David Thornley 2010年

tcrosley-我要补充一点,就是因为它来自Fortran,所以没有理由继续这种做法。我强烈不鼓励使用称为“ i”,“ j”,“ k”等的迭代器/循环计数器。这是显而易见的惰性。无处不在<>好。
quick_now 2011年

9

它们不如误导性标识符那么糟糕。我不介意调试其中标识符只是一个字母的代码,但是一旦图片中使用不同的命名约定,它就会变得很烦人。例如,如果在某处看到strPersonID,然后又在某处看到s_EmployeeID,则很难分辨这两个字符串是否相同以及是否存在差异。另外,如果变量是复制粘贴(pmapIntString = new std::map<int,int>)且完全错误,我会担心。

当涉及到我时,我在代码中添加了所用重要变量的注释,并尝试维护开发指南中给出的标准。如果没有标准,那么我会尝试在整个代码中保持相同的命名约定。


5

我奋斗...

我过去总是将描述性名称用作标识符,但是最近我使用了非常短的标识符。

我认为,这取决于代码的上下文:

  • 如果您编写复杂的函数(算法),则始终使用短标识符(最好使用单个字符)
  • 在编写函数的参数值时,请使用描述性名称。

我想这还取决于代码的密度。有时候,拥有名称实际上会使阅读变得更加困难。

有时没有名字,那完全是神秘的!


1
但是,如果您正在编写复杂的算法,那么您是否不希望标识符对第一次查看您的代码的人更具描述性?
Maxpm 2010年

什么时候适合使用单个字符标识符?
阿米尔·阿富汗尼

1
我曾经也认为,但实际上我发现情况并非如此,请自己尝试。采用复杂的算法,并尝试使用描述性名称与单字母变量。
2010年

1
我同意,但仅适用于较长的复杂公式,因为它们往往变得太长,即使那样,您也可以使用函数(函数名)来描述该公式的哪些部分。
Emile Vrijdags,2010年

1
如果它是复杂的,并具有模式,这些模式应该被细分为功能
CaffGeek

3

我的想法是,它们本身并不不好,但是除非它们非常标准,否则它们不会提供信息。

因此,循环变量i,jk非常标准,因此在创建索引循环时没有理由不使用它们。

我将使用一个非常短的标识符的另一个地方是当我声明一个临时变量,该临时变量将在几行时间内超出范围时,例如,来自foreach循环的临时变量。如果在其他任何地方都不会引用它,那么阅读代码的任何人都可以很容易地看到该声明并遵循该声明的用途。但是,如果要用于多于五行或六行,我会给它起一个更清晰的名称。

除此之外,我尝试使用信息长度标识符-特别是在类级别,我希望您可以读取一个标识符并了解变量的用途。如果它们变得太长(有时我确实看到代码,其中有四个或五个单词串在一起作为标识符),我倾向于将其视为代码的味道-如果我需要那么多文本来区分变量,它们实际上是一组可以更好地存储在哈希图或列表中?我可以创建某种对象来更准确地对数据建模吗?有时,您不能但很长的标识符表明这里值得一看。


3

我非常同意这里的其他答案,但想指出我认为经常被忽略的另一个因素。好的名称通常是代码惯用的名称。这可以是语言级别,算法级别,也可以是现有代码库的一些内部习语。关键是,尽管名称可能对不知道代码域的人毫无意义,但在给定的上下文中,它仍然可能是最好的名称。


3

命名变量始终是平衡唯一性和可理解性的一种做法。名称的长度以不同的方式与两者相关。长名称更容易使其唯一;中等长度的名称比太短或太长的名称更容易理解。

如果它有一个历史,使得它易于理解的一个很短的变量名是唯一有用的(例如ij,和k为指数; dx沿轴的距离)或范围是足够小的所有引用视为一次可见(如,temp)。世界上最差的变量名是t47。(“这是什么意思,为什么与?有什么不同t46?”)谢天谢地,命名方式主要是用FORTRAN淘汰的,但这正是人们希望使用更长的变量名的地方。

正如您的原始论文所显示的那样,过长的名称也很难读,因为在浏览代码时可能会忽略细微的内部差异。(DistanceBetweenXAxisAbscissae&之间的区别DistanceBetweenYAxisAbscissae确实很难迅速理解。)

正如NoteToSelf之前指出的,名称唯一性的要求主要取决于名称必须具有唯一性的范围。5行循环的索引可以为i; 从函数传递到函数的活动记录的索引最好使用更具描述性的名称。

函数局部变量可以有一个小的描述性名称,就像deltaX没有问题一样。模块中的静态delta X变量必须具有一个名称,该名称可将此deltaX与同一模块中的其他deltaX区别开来,从而使其更长。并且必须使所有模块以及可能创建的所有其他可能模块中的全局delta X变量唯一,这可能是通过将模块名称连接到其他描述性名称来实现的。这是全局变量的众多问题之一。为了使名称唯一有用,名称必须足够长,以使其难以阅读。


2

相反,我认为长标识符比短标识符差(除非您要处理常量)。与使用相比,使用TheVariableThatHoldsTheCapacityOfMyContainerClass会使您的代码更容易出错Capacity


1
您很高兴知道,我所链接的一项研究支持您的推理,如果不是出于相同的原因,那么。;-)
Daniel C. Sobral 2010年

1
误读很长的标识符也很容易,可能使它们混淆或无法意识到它们中的两个是相同的。
David Thornley 2010年

2
TheVariableThatHoldsTheCapacityOfMyContainerClass比我认为的“长”要大-十个单词对于CamelCase不能帮助太长;您需要空格使其可读。
理查德·加兹登

1
当然,但这是一个稻草人。您的长名示例增加了词缀,但没有任何信息。考虑一下您具有与各种形式的能力相关的多个变量的情况。然后,您真的可能想要区分用途的名称,例如initalCapacity或finalCapacity。
查尔斯·格兰特

2
@Maxpm,var total = Capacity + Capacity2; 什么是Capacity包含,又是什么Capacity2内容?它们将用于什么用途?必须寻找上下文线索会浪费时间。鉴于它是按var totalStorageCapacity = truckCapacity + trailerCapacity;我所知道的写的。
CaffGeek

2

就其本身而言,短标识符也不错。选择好名(短或长)的目的是为了使代码清晰。 在代码清晰的服务中选择标识符比满足某些最小长度要求更为重要。 通常,这意味着写更长的有意义的名称。


+1您说得非常好,写答案时我找不到我的话:-)
ComputerSaysNo 2010年

1

我多年来的观察,今天的观察要少于10或15年前。不能键入的程序员会因可变的命名而使您不胜其烦。它们是所有1-3个字母变量名称的名称。

因此,我的建议是使用许多评论者所说的有意义的名称,然后学习打字。我一直在考虑在面试中添加打字测试,只是为了看看人们在哪里,但是随着计算机成为社会中更重要的一部分,我开始看到的非打字员越来越少。


2
实际上,我还没有看到这种关联。如果有的话,那么面向对象语言的人会使用长标识符,而使用功能语言的人会使用短标识符。确实质疑OO有助于建模的指控。:-)
Daniel C. Sobral

不要忘记,不仅需要键入名称,还需要阅读名称。使用太长的标识符实际上可能会大大降低可读性。法律禁止i在循环之外使用任何东西for (int i=0; i<dst.size(); ++i) dst[i] += src[i]
maaartinus 2011年

1

您链接到的第一篇论文看起来很有趣,但是结论是,他们没有发现支持或反对“基础提示”(包括有意义的变量名)有助于代码理解的假设的重要证据。所用的凝视停留时间作为代码理解的代理,这很有趣,但不是灌篮。

恐怕我发现第二篇论文很愚蠢。第一个问题是它们提供的长名称示例很长,没有提供额外的信息。我认为我们都可以同意,使变量名变长只是为了使其变长是愚蠢的。他们命名可变的distance_between_abscissae而不是dx的示例是一个稻草人。

更重要的是,他们的实验是对简单记忆而非理解的测试。当在没有上下文的列表中显示时,它可以测试主题​​填充变量名缺失部分的能力。是的,较长的名称很难记住,但是在编码时,我不记住变量名,而是使用它们来提供上下文。我想您可能会争辩说,记住长变量的困难使代码难以编写,但是代码的读取次数比编写的要多,因此应该优化哪个活动?


请注意,第二篇论文明确指出“八个问题中使用的八个名称是从生产代码中提取的”。而且,他们不仅测试记忆力,还测试正确性。
Daniel C. Sobral

1

我确定某行代码是否可读的主要指标之一是必须从其他行读取多少其他上下文,以真正确保您了解该行在做什么。

可以很容易地说“任何人都应该能够理解i,j和k是循环变量”。在大多数情况下,这确实很明显。但是我仍然尝试对此保持谦逊和专业,并假定在编程时很容易犯错误。因此,如果我遍历Grobbles数组,我将命名循环变量grobbleIndex。我也可以接受i作为index的缩写。当您使用ij和k时,很难发现错误,例如使用错误的索引和错误的数组等等。当您有一个内循环时,情况甚至更糟。

PS。在我写这个答案的时候,我正在用垂直分割的屏幕在vim上的10英寸迷你笔记本电脑上编码一些javascript,但我仍然花时间命名循环变量rowIndex和columnIndex。


0

在某些应用程序中,短变量根本无法解释变量中的数据。短还是长无关紧要。使用较长的变量不会使您的代码变慢。当然,键入一个长的变量名需要更多的努力,但是至少六个月后(可能是您)阅读代码的人(即使是您)也可以找出正在发生的情况,而不必假设甚至有可能。


0

我认为理想的情况是名称应具有描述性,除非 ...

如果名称范围有限,则名称可以(也许应该)简短的想法(因此暗示性较少)是偏离理想的一个原因。

就我个人而言,我经常为少数重复引用的实体使用简称。例如,经常调用特定于应用程序的子例程。


-2

我永远不会使用少于4-5个字符的标识符名称,例如,一个循环变量可能是Index或jIndex或kIndex,这取决于我需要完成多少内部循环,但是对于其他名称,我会说一个“键”如果是方法变量,则为本地字符串“ String LKey”或“ int LKey”,“ L”;对于私有类变量,为“ F”;所有其他标识符(如我之前提到的其他标识符)都应以其名称解释其存在的原因,否则“标识符”范围是没有用的吗?


5
“索引”赋予什么“ i”没有什么附加信息?长变量名什么也没告诉你,比单字符名差。
Anon。

2
最近写了一些在3d网格上工作的东西后,我有了许多名为x,y和z的变量。在上下文中,它们完全是描述性的。
Loren Pechtel 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.