短变量名有借口吗?


140

对于我目前正在使用的代码库,这已经变得非常沮丧。我们的许多变量名都很简短且没有描述性。我是该项目上剩下的唯一一名开发人员,并且没有关于它们大多数功能的文档,因此我不得不花更多的时间来跟踪它们的含义。

例如,我正在阅读一些更新光学表面定义的代码。开始时设置的变量如下:

double dR, dCV, dK, dDin, dDout, dRin, dRout
dR = Convert.ToDouble(_tblAsphere.Rows[0].ItemArray.GetValue(1));
dCV = convert.ToDouble(_tblAsphere.Rows[1].ItemArray.GetValue(1));
... and so on

也许只是我一个人,但实际上它们告诉我的内容并没有告诉我,这使得进一步理解代码变得困难。我所知道的是,它是一个变量,该变量从某个地方的特定表中解析出特定行。经过一番搜索,我发现了它们的含义:

dR = radius
dCV = curvature
dK = conic constant
dDin = inner aperture
dDout = outer aperture
dRin = inner radius
dRout = outer radius

我将它们重命名为基本上我在那里所拥有的。它延长了一些行,但是我觉得这是一个公平的权衡。但是,在许多代码中都使用了这种命名方案。我不确定这是来自开发人员的作品,他们是通过使用较旧的系统而学习的,还是背后有更深层的原因。是否有充分的理由以这种方式命名变量,还是我在遇到变量时将其更新为更具描述性的名称是否合理?


98
在我看来,在那种特定情况下,那些是直接从长期数学公式中复制的变量名。
Dave Nay 2012年


35
如果您发现由于变量名简短而无法理解数学代码,请注意,这可能是因为您不了解数学,而不是因为名称太短。更改您不了解的数学表达式并不是一个高可靠性的过程。一旦理解了数学,变量名的长度就无关紧要了。不过,如果需要学习,请别人帮个忙,并在数学的一些相关描述中留下引用(在评论中)!
Rex Kerr

3
以大金刚命名的任何标识符都可以通过:dK = conic constant
Thomas Eding

8
相反,人们可能会问,对领域字段的无知是否可以忽略其约定。最后,它取决于上下文。
Daniel C. Sobral

Answers:


234

这些变量名称似乎是基于您期望在物理学教科书中找到的有关各种光学问题的缩写。这是短变量名通常优于长变量名的情况之一。如果您有习惯使用Rin,Rout等常用缩写的物理学家(或习惯于手工求解方程式的人员),则使用这些缩写的代码将比使用较长的变量名的代码更清晰。它还使将论文和教科书中的公式与代码进行比较变得容易得多,以确保代码实际上在正确地进行计算。

任何熟悉光学的人都会立即识别出Rin作为内半径(在物理学论文中,in将其表示为下标),Rout视为外半径等。尽管他们几乎可以肯定地能够在心理上翻译某些东西就像innerRadius更熟悉的命名法一样,这样做会使该代码对那个人不太清楚。这将使得发现熟悉的公式被错误编码的情况变得更加困难,并且使得将代码中的方程式与在纸张或教科书中找到的方程式进行相互转换也变得更加困难。

如果您是唯一查看此代码的人,则无需在代码与标准光学方程式之间进行转换,物理学家不太可能将来需要查看该代码,也许重构是有意义的,因为缩写的好处不再超过成本。但是,如果这是新的发展,几乎可以肯定的是,在代码中使用与文献中相同的缩写。


17
并且如果工作人员中没有物理学家或数学家?代码基本上留给我了。基本上没有记录。阅读描述性名称会困难吗?
KChaloux 2012年

127
+1期望程序员理解他所从事的领域并不是没有道理的。另一方面,在数学工作中,变量通常在方便的地方定义。在这样的代码中,我期望显示长格式的突出注释。
Karl Bielefeldt 2012年

15
+1:您基本上要说的是,了解他们正在工作的域的程序员将理解变量名。即使变量名较长,在许多项目中也是如此。例如。column在军事策略游戏中命名的变量很可能意味着与图表软件不同的含义。
史蒂文·埃弗斯

23
在医学程序设计中,您经常会发现在编程领域中存在的术语。例如,对于眼科,您将看到OU,OD和OS。这些表示哪只眼睛,例如ouSphere可以引用右眼眼镜处方中的“球体”组件。如果您了解要为其编程的业务领域,那么您将成为一名更好的程序员。
条例草案

11
+1表示与论文和文本中的方程式和公式匹配的简称。在执行此操作时,我会提供有关在哪里可以找到原始参考资料的评论。
杰伊·埃尔斯顿

89

寿命短的变量应简短命名。举例来说,您无需编写for(int arrayCounter = 0; arrayCounter < 10; arrayCounter++) { ...。而是使用for(int i ...

根据一般经验,可以说变量范围越短,名称应越短。循环计数器往往只有单个字母,说ijk。局部变量类似baseor或fromand to。例如,全局变量在某种程度上更加精细EntityTablePointer

您使用的代码库可能未遵循这样的规则。这是进行一些重构的一个很好的理由!


14
数组索引的i,j和k至少可以追溯到Fortran。任何自重的程序员都将熟悉此约定。
Dominic Cronin

7
我一般不写ijk,我喜欢写东西personPos,因为那时我不会忘记我在迭代,什么该指数代表。
马尔科姆

18
-1,我确实使用长名称进行数组索引迭代,但是我给它们起了有意义的名称,而不是显而易见和毫无 意义的名称arrayCounter。使代码更易于阅读,并且至少在复制/粘贴此内部循环时使您免于踩踏整个外部计数器。
Oleg V. Volkov,2012年

3
counter是名词或形容词。Count是名词或动词。当然,我仍然不会打电话给arrayCounter我,我会使用personIndex或使用row任何描述我正在查看的内容。
韦恩·沃纳

6
在执行单循环时,请使用i。但是,一旦我过渡到嵌套循环,就放弃了i命名法。这样做的原因是因为我真的想跟踪正在使用哪个循环变量,而在密集代码中,ivs j可能会很欺骗。对我来说,使它更具可读性并增加更多的空格是固有的必要。
jcolebrand

48

代码的问题不是短名称,而是缺少注释(该注释可以解释缩写),或者指向一些有关导出变量的公式的有用材料。

该代码仅假设问题域熟悉。

很好,因为问题域的熟悉度可能是理解和维护代码所必需的,尤其是在“拥有”该代码的人的角色中,因此,您应该获得熟悉度,而不是四处张名。

但是,如果代码提供一些提示以用作跳板,那就太好了。即使是领域专家也可能忘记这dK是一个圆锥常数。在评论栏中添加一些“备忘单”不会有问题。


最终最终得到了这样的东西。
KChaloux 2012年

5
错了 没有理由使您的代码难以阅读,以迫使人们花更多的时间“学习”它。您不是在教书,只是在让别人慢下来。而且,实际上永远不会永远只有一个代码所有者。您是近视和自私的人。
xaxxon

7
错误的是你的解释,而不是答案。该代码实现了一些存在于该代码之外且独立于该代码的数学运算。保持相同的命名是有帮助的。维护代码的人可能必须在数学之外学习,而不必在两个命名方案之间映射会帮助该人。
卡兹(Kaz)

19

对于问题域中众所周知的某些变量(例如您在此处的情况),简洁的变量名是合理的。如果我正在开发游戏,则希望游戏实体具有位置变量xy,而不是horizontalPositionverticalPosition。同样没有超出索引任何语义的循环计数器,我希望看到ijk


我认为cv,din和dout并不是立即显而易见的(尽管它们显然是在特定领域建立的)。我不会讨论x和y,因为笛卡尔坐标适用于任何数量的字段,并且对中学和高中的每个人都有教益。
KChaloux 2012年

1
xy,而普通,不携带像隐含重要的方面,其中,在原点。
罗斯帕特森

3
@RossPatterson:但是,在许多情况下,这根本不重要。例如,考虑如下循环for (x,y) in list_of_coordinates: print x,y:尝试理解代码时,原点并不重要。
布莱恩·奥克利

16

根据“清洁代码”:

变量名称应:

  • 有意透露
  • 避免虚假信息
  • 做出有意义的区分
  • 明显
  • 可搜寻

异常是i,j,k,m,nfor循环中使用的谚语。

变量名称是您理所当然地抱怨的,上述都不做。这些名字是坏名字。

另外,由于每个方法都必须为short,因此请使用前缀指示不再使用作用域或类型。

这个名字更好:

radius
curvature
conicConstant
innerAperture
outerAperture
innerRadius
outerRadius

评论者说,使用长变量名会太复杂:

在此处输入图片说明

简短的变量名也不会让它变得简单:

fnZR = (r^2/fnR(1+Math.sqrt((1+k) * (r^2/R^2)))) + a[1]*r^2 + a[1]*r^4 + a[1]*r^6 ...;

答案是长名称和中间结果,直到最后得到以下内容:

thisNiceThing =  ( thisOKThing / thisGreatThing ) + thisAwsomeThing;

26
这些变量可能在代码中的数学公式中使用。数学公式太多容易阅读短变量名。我在大多数代码中都使用长变量名,但是数学上最好使用短变量名。随便举个例子:考虑多久,将与长变量名。
MarkJ 2012年

@MarkJ你是对的。
图兰斯·科尔多瓦

1
中间结果具有减少和隔离编程错误的额外好处。我们的大脑一次只能处理这么多的信息,很难在类似这样的地方发现错误fnZR = (r^2/fnR(1+Math.sqrt((1+k)) * (r^2/R^2))) + a[1]*r^2 + a[1]*r^4 + a[1]*r^6 ...;
眼睑失明

1
如果那是您的面包和黄油,那并不难。
Radu

1
重点不是写单线。但问题是,如果你需要改变一些东西,并使用另一个公式,现在你有它需要很长的时间来找出哪些问题long_nameR教科书指。使用中间结果,但使复杂的数学尽可能靠近问题域,以便在需要添加功能时可以实际维护它。
slebetman 2014年

8

有两个很好的理由不重命名遗留代码中的变量。

(1)除非您使用自动重构工具,否则引入错误的可能性很高。因此,“如果没有损坏,请不要修复”

(2)您将比较当前版本与过去版本,以查看更改内容是不可能的。这将使以后的代码维护更加困难。


7
绝对正确,但是缺乏理解的风险更大。
罗斯·帕特森

2
如果您的工具无法处理您提到的简单问题,那么您将遇到更大的问题。
2012年

答案(1)合理的自动测试范围和合理的封装,(2)熟练掌握版本控制。
Adamantish

5

是否有充分的理由以这种方式命名变量,还是我在遇到变量时将其更新为更具描述性的名称是否合理?

使用较小名称的原因是,如果原始程序员发现它们更易于使用。大概他们有权发现这种情况,并且有权不拥有与您相同的个人喜好。就个人而言,我会发现...

dDin better than dDinnerAperture
dDout better than dDouterAperture

...如果我在长时间的复杂计算中使用它们。数学表达式越小,通常越容易一次看到整个事物。尽管是这种情况,但它们可能比dIn和dOut更好,因此没有重复的D可能导致简单的错字。

另一方面,如果您发现使用起来比较困难,则将自己淘汰,然后重命名为更长的形式。特别是如果您负责该代码。


7
至少我肯定摆脱了系统匈牙利表示法...
KChaloux 2012年

4
领导d是匈牙利人?我以为是微积分dx^2/dx = 2x
Shannon遣散费

7
如果我自己看dDinnerAperture的话,我会把它读为“晚餐光圈”,并且想知道这是否只是说“你的嘴”的有趣方式。从来没有“大写字母后跟小写字)风格的粉丝非常混乱的时候。。
达雷尔·霍夫曼

2
+1这就是答案。龙的数学公式是很多容易阅读短变量名。这些变量可能在代码中的数学公式中使用。数学公式太多容易阅读短变量名。我在大多数代码中都使用长变量名,但是数学上最好使用短变量名。随便举个例子:考虑多久,将与长变量名。
MarkJ 2012年

1
@ShannonSeverance我同意你的看法。来自工程学背景,在数学意义上使用变量名时,d一定要保留给微积分(正如这里经常提到的)。
CodeMonkey

4

通常,我认为这是应该遵循的规则,即您可以使用非常简短的变量名,因为您知道特定代码的“技术熟练”人员会立即理解该变量名的引用。(无论如何,对于这种情况,您总是会有注释),并且可以根据变量的使用方式来轻松地区分变量的本地化用法。

为了对此进行扩展,这意味着您不应该费力地混淆变量名,但是,可以对变量名使用缩写,在这种情况下,您知道只有了解代码基本概念的人员才有可能仍然要阅读它。

以一个真实的例子为例,最近,我正在创建一个Javascript类,该类将具有一定的纬度,并告诉您在给定日期所期望的日照量。

为了创建此日d类,我引用了六种资源(《天文学年鉴》)以及其他语言(PHP,Java,C等)的摘要。

在几乎所有这些词中,他们都使用相似的相同缩写,从表面上看绝对没有任何意义。

KTEPSdeltaPsieotLMRA

但是,如果您具有物理知识,则可以理解它们的本质。我不希望其他人接触到此代码,所以为什么要使用冗长的变量名?

julianTimenutationOfEclipticalLongitudeExpressedInDegreesequationOfTimelongitudeMeanrightAscension

另外,很多时候,当变量名是暂时的时,也就是说,它们仅用于临时分配一些值,那么使用冗长的版本通常是没有意义的,尤其是在变量的上下文中解释它的目的。


1

绝对有;通常,短变量名是必需的。

就我而言,我在高级机器人学课程中进行航点导航,并且我们在KISS-C中对机器人进行编程。我们需要用于当前和目标(x,y)坐标,(x,y)距离,当前和目标航向以及转弯角度的变量。

特别是在x和y坐标的情况下,完全不需要长的变量名,并且诸如xC(当前x),yD(目标y)和pD(目标phi)的名称就足够了,并且最容易理解在这种情况下。

您可能会争辩说,这些不是程序员协议所规定的“描述性变量名”,但是由于名称是基于简单的代码(d =目标,c =当前),因此一开始就非常简单地说明了所有描述他们需要。


0

是否有充分的理由以这种方式命名变量,还是我在遇到变量时将其更新为更具描述性的名称是否合理?

通常,复杂的算法以matlab(或类似语言)实现。我看到的是人们只是接管了变量名称。这样,比较实现就很简单。

所有其他答案几乎都是正确的。这些缩写可以在数学和物理学中找到,除非它们不是以d(如您的示例)开头。以d开头的变量通常被命名为代表微分

所有普通的编码指南都要求不要以第一个字母代表类型来命名变量(如您的情况),因为在所有现代IDE中浏览代码非常容易。


是的,不管人们最终怎么说,这个要素都将消失。在我发现的代码库中,正在发生一种半匈牙利半非精神分裂症。
KChaloux 2012年

0

我可以想到变量名要简短的原因。

短名称易于使用较短的跨度阅读,因此注意范围短。

例如,一旦我习惯了svdb意味着“保存到数据库”这一事实,对源代码的扫描速度就会变好,因为我只需要快速扫描4个字符,而不是在读取SaveToDatabase时(14个字符,情况会变得更糟)。以获取更复杂的操作名称)。我说“扫描”而不是“读取”,因为这是分析源代码的主要部分。

在扫描大量源代码时,这可以提供良好的性能提升。

而且,它仅有助于懒惰的程序员在编写代码时键入这些短名称。

当然,所有这些“速记”都应该在源代码的某些标准位置列出。


1
我们不会将单词作为一组字符来阅读,而是将它们作为形状来阅读,并在快速理解失败时有条件地解析细节。一个单词要花更长的时间才能阅读的长度远大于4个字符,并且我们能够在头脑中处理camelCase和其他方法来分解可变名称单词作为单词边界。我怀疑阅读测试是否会证明短名称会提高阅读理解速度。取而代之的是,删除可识别的单词会降低速度,直到吸收新单词(您自己指出)。
眼睑失明

0

以略有不同的方式来构造@zxcdw所说的内容,并在方法方面进行详细说明:

功能应该是纯净的,简短的并且完美地封装了某些功能:黑匣子逻辑,无论是否静置了40年,它都将继续执行其设计的工作,因为其接口(输入和输出)是声音,即使您对其内部一无所知。

这是您要编写的代码类型:这是持久的代码,易于移植。

必要时,可以从其他(内联)函数调用中组合函数,以保持代码的细粒度。

现在,使用适当的描述性函数名称(如有必要,请加上详细说明!),由于范围太小,我们可以最大程度地减少误解这些缩写变量名称的机会。


-1

变量名应尽可能地具有描述性,以帮助提高程序的可读性。您自己亲身体验了:由于命名不佳,您很难确定程序的功能。

没有充分的理由不使用描述性名称。这将对您以及其他将在项目中工作的人有所帮助。那么实际上有一个单一的短名称的有效利用:循环计数器。


6
请注意,int dummy_variable_for_for_loops;它尽可能具有描述性。
卡兹(Kaz)2012年

4
-1,因为此答案令人困惑。首先,它说没有充分的理由,然后最后说实际上是有的。如果改写不矛盾,答案会更好。
Bryan Oakley

我将其更改为“根据需要进行描述”。如果缩写表示变量的目的,则可以使用缩写
Maximus

-1

//这肯定是//注释的目的吗?

如果作业中有描述性的注释,那么您将两全其美:对变量任何方程的描述都可以轻松地与教科书中的变量进行比较。


-1

对于接口(例如方法签名,函数签名),我倾向于通过注释参数声明来解决。对于C / C ++,这会修饰.h文件以及实现的代码。

对于变量声明,我也做同样的事情,因为在上下文和命名中不知道变量的用法。(这适用于也没有强类型的语言。)

很多事情我们都不想阻塞变量名。角度(以弧度或度为单位),在精度或范围上是否存在一定的公差等。该信息可以提供有关必须正确处理的特征的有价值的主张。

我对此并不虔诚。我只是对清晰性感兴趣,并希望确保现在我下次忘记的自我访问代码时是什么。看着我的肩膀的每个人都有他们需要知道的内容,以了解哪些地方出了问题,什么是必不可少的(正确维护的最后一个关键)。


-1

变量名过短是否有借口吗?

第一:在计算公式如E为命名能量E的可变= MC2是NOT过短的命名。用符号作为参数短名称是无效

这个问题对我来说很有趣,我只能想到一个借口,那就是金钱。

例如说你对哪知道该文件是要下载一个客户端的JavaScript接线许多次。如果文件(以字节数为单位)越小越好,它会更便宜并且使用户的体验更好。

(仅是为了保持示例的“真实性”,不允许您使用压缩工具,为什么?安全问题,不允许使用任何外部工具接触代码库。)


1
您的示例仍然不是很现实。
Radu

-1

我注意到其他答案没有提到匈牙利符号的使用。这与长度辩论正交,但通常与命名方案有关。

double dR, dCV, dK, dDin, dDout, dRin, dRout

所有这些变量开头的“ d”表示它们是双精度的。但是该语言仍在强制执行此操作。尽管这些名称很简洁,但它们最多可以冗余 50%!

如果我们要使用命名约定来减少错误,那么最好对由语言检查的信息进行编码。例如,dK + dR即使在长度上添加无量纲数字也没有意义,但在以上代码中没有语言会抱怨。

防止此类错误的一种好方法是使用更强的类型。但是,如果我们要使用双精度,则更合适的命名方案可能是:

// Dimensions:
// l  = length
// rl = reciprocal length
double lR, rlCV, K, lDin, lDout, lRin, lRout

该语言仍然允许我们编写K + lR,但是现在这些名称提示我们这可能是错误的。

这是系统匈牙利语(通常较差)和Apps匈牙利语(可能较差)之间的区别

http://en.wikipedia.org/wiki/匈牙利语


1
实际上,K + lR 如果您正确声明单元,C ++可能会抱怨。使用SI单位,它可以进行尺寸检查和单位转换。添加3_feet + 2_meter应该没有问题,而2_meter+1_second应该是编译时错误。
MSalters 2014年

@MSalters太酷了;我还没有想到一个模板/宏方法。尽管如此,在这样的“与语言无关”的问题中,无论语言是否被称为“类型”,我都会将所有编译时单元检查

模板,必不可少。您不能在宏中进行必要的类型演算。
MSalters 2014年

-2

在现代软件工程中,唯一的可接受的简短变量名的情况是它们存在于脚本中并且该脚本的吞吐量(通常通过网络)很重要。即使这样,在源代码管理中保留长名称的脚本,并在生产中最小化该脚本。


9
当执行将这些术语视为领域内的常识的数学运算时,会怎么样?示例:在e = mc ^ 2中使用M代替“质量”
Andy Hunt 2012年

2
@andyBursh-我会在那儿小心。程序员在他们的问题领域通常不是专家(甚至是主管)。就是说,这样的事情可以没事,尤其是如果有适当的注释链接到所讨论的公式;那么 我已经忘记了这种情况。
Telastyn

8
@Telastyn-但是,如果您假设程序员不是专家,那通常会导致使用含义非常明确的缩写并将其转换为至少有点含糊的较长名称(即有人决定命名局部变量)radius当它存储内半径时,不了解比(Rin)含糊得多。然后,每当涉及方程式的讨论时,非专家开发人员就必须在其独特的术语和企业理解的术语之间进行转换。
贾斯汀·凯夫

2
循环计数器的“ i”怎么办?或在处理坐标时使用“ x”和“ y”?还是范围只有两行代码的变量?
Bryan Oakley

4
不赞成这个答案。从事包含复杂数学表达式的程序的程序员最好至少能够阅读规范中的公式,否则它们将不起作用。那不是问题领域的知识,而是必不可少的技能-在从事数学程序之前需要具备一些基本的数学能力。如果程序员无法访问规范公式,那将是另一个问题-不能仅通过注释来解决。
MarkJ 2012年
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.