在局部变量(例如,employeeCount,firstName)中的第一个单词使用小写的原因是什么?


20

由于我对所有变量都使用了完全正确的大小写形式,因此引起了其他程序员的大量批评。例如,您的典型程序员将使用employeeCount变量名,但我使用EmployeeCount。我对所有内容都使用完全正确的大小写,无论是void方法,return方法,变量,属性还是常量。我什至在Javascript中都遵循此约定。最后一个确实震撼了人们的傻瓜。

关于为什么我不应该遵循这种“非标准”大写字母约定的典型原因是,应为属性和void方法保留完整的适当大小写。局部变量和返回值的方法的首字母应小写,例如int employeeCount = getEmployeeCount()。

但是,我不明白为什么。

当我对此提出疑问时,似乎只能得到一个任意的答案,那就是标准。不管答案是什么,它通常总是归结为这就是它的样子,我对此并不怀疑。我只是跟随它。。任意答案对我来说永远不够好。

自从使用Office IDE对Excel 97宏进行编程的早期开始,我就不需要用大小写约定来告诉我某些东西是局部变量还是属性。这是因为我一直使用非常直观的命名约定。例如,GetNuggetCount()很明显地提出了一种方法,该方法可以计算所有矿块的数量。 SetNuggetCount(x)建议您为块数分配一个新值。 NuggetCount所有这些本身都暗示了仅包含值的属性或局部变量。对于最后一个,可能会想说:“啊哈!这是问题。属性或变量?这是什么?” 为此,我会回答:“这真的重要吗?”

因此,这就是tl; dr ;:在变量或return方法中的第一个单词使用小写字母的客观,逻辑,非任意原因是什么?

编辑: 对于MainMa

将此代码替换为答案中的第一个代码示例,然后查看您的论点是否成立:

public void ComputeMetrics()
{
    const int MaxSnapshots = 20;

    var Snapshots = this.LiveMeasurements.IsEnabled ?
        this.GrabSnapshots(MaxSnapshots, this.cache) :
        this.LoadFromMemoryStorage();

    if (!Snapshots.Any())
    {
        this.Report(LogMessage.SnapshotsAreEmpty);
        return;
    }

    var MeasurementCount = Measurements.Count();
    this.Chart.Initialize((count + 1) * 2);

    foreach (var s in Snapshots)
    {
        this.Chart.AppendSnapshot(s);
    }
}

7
如果它们是大写的,那么会有其他人问他们为什么不是小写的……
— m3th0dman

11
如果我们功能强大的IDE可以有一个插件来映射我们自己对样式问题的个人偏好,并允许我们在后台使用它们,以应用源文件的“真实版本”,那不是很好吗? “项目的”样式语义。在您需要审核正式文件版本之前,这完全是视觉问题。只是在做梦...
— Sassafras_wot13年

59
对于您来说不幸的是,实际和有效的原因是“因为这是标准”。它要求同一团队中的人员遵循相同的代码样式标准。如果您不明白为什么,那么也许您应该问另一个问题:“为什么标准有用?”
— Andres F.

3
我一直以为开发人员选择了camelCase,因为它看起来很扭曲。在PascalCase之上,没有camelCase 本身的 “客观”原因。我个人发现PascalCase(如您的示例)更易于阅读,并且可以在除JavaScript之外的其他大多数地方使用它,因为我会一直使用camelCase,所以我不会错过聚会邀请。
— GrandmasterB

7
研究具有标准编码样式的优点真正遵循什么标准并不重要。
— Mindor先生

Answers:


88

当人们希望为变量赋予与变量名称相同的名称时,通常使用该命名约定。例如:

Employee employee;

有些语言甚至强制使用大写字母。不必使用恼人的变量名像这样可以防止MyEmployee,CurrentEmployee,EmployeeVar等你总是可以告诉我们,如果事情是一个类型或一个变量,仅仅从资本。这样可以避免在以下情况下造成混淆:

employee.function(); // instance method
Employee.function(); // static method

另外,在英语中,名词通常不大写,因此您不能真正声称自己的大写是“正确的”。

那与您的情况有什么关系?显然,阅读自己的代码没有问题,但是通过保持尽可能一致,可以减少其他需要阅读代码的人的工作量。以书面形式编码时,您可以调整样式以适合读者。


1
请注意,由于属性使用大写字母,因此问题仍然存在于OP使用的语言中(当然,属性可以使用前缀this.,这避免了混淆;局部变量不能使用此类前缀)。
— Arseni Mourzenko 2013年

1
@oscilatingcretin,它称为PascalCase。
— Mindor先生,2013年

21
Employee Employee可以,但我认为这比令读者更困惑Employee employee。后者看起来像两件事。第一次看起来像不必要的重复。
— 杰米·F

14
确切地说,@ oscilatingcretin:“假定读者理解底层框架……”我喜欢阅读JavaScript,Java,C#,C ++等,并在我脑海中翻译代码。我不想一直思考“哦,这种语言的编译器可以处理x”。而我只是想了解代码的含义。
— 杰米·F

1
请注意employee.function(),如果语言允许从对象调用静态方法(如Java),则这也可能是静态方法。编译器会给出警告,但可以这样做。
— Uooo 2013年

34

没有 这是大多数人的工作,因此它已成为标准,因为这就是每个人的工作。许多文献都遵循这一惯例,所以人们逐渐习惯了。

约定不如整个代码的一致性那么重要。只要以一致的方式命名所有内容,以便我可以通过查看它们来分辨出什么,首字母是否大写并不重要。

我发现遇到碰到以您的方式编写的代码会感到不高兴,并说我不喜欢它。但这是风格问题。

现在,如果您在工作场所中这样做,最好以团队风格进行编码,以使代码在任何地方都保持一致。而不是让您的代码与其他所有人不同。

http://thecodelesscode.com/case/9​​4


3
我希望大多数程序员都像你一样。许多人对遵循我提到的套管标准充满热情和/或教条。
— oscreatingcretin

1
@Schieis很重要,如果您是下一个从事该项目的程序员。
— N4TKD

3
@oscilatingcretin一旦处理了充满了代码,您可能最终会变得热情和/或教条var m_someVariableID = GetVariableValueId()。特别是如果您必须在没有自动补全支持的情况下执行此操作。
— Tacroy

7
如果您在团队中,那么遵循该团队的标准很重要。但是请注意,在团队没有标准(或团队推迟要求您设置标准)的新项目中,许多编程语言都有事实上的标准,您应该尝试遵循这些标准。如果您不确定要使用哪种编码约定,则遵循主要语言供应商或所包含框架使用的约定比您自己的标准更可取,除非您可以证明自己的标准合理。
— 布莱恩

2
@Schleis很好的更新,我不同意这只是样式问题,但是约定和约定由于有充分的理由而成为约定,因此应该遵循。它不是一种宗教,有时您必须完全符合惯例,但您应该有充分的理由。
— N4TKD

25

1.为什么存在该标准?

毕竟,让每个人都根据个人喜好编写代码,而不再谈论哪种标准更好是不是更好?

事实是,当您习惯一种样式时,阅读使用另一种样式的代码会更加困难。您的大脑会花更多的时间来尝试理解约定(如果有),而不是去理解代码的作用。

这两段代码之间更有可读性吗?

public void comp_metrics ()
{
  int Count;
  List<snapshot> measurements=fromMemoryStorage();
  if (_liveMeasurements.enabled)
    measurements = GrabSnapshots(20, _cache);
    if( !measurements.Any() ) {
        this.Report(LogMessage.Measurements_Are_Empty); return;
    }

    Count = measurements.Count ();

    this.Chart.initialize(( Count + 1 )*2);

    foreach(snapshot S in measurements) {
      this.Chart.append_Snapshot ( S );
    }
}

要么:

public void ComputeMetrics()
{
    const int MaxSnapshots = 20;

    var snapshots = this.liveMeasurements.isEnabled ?
        this.GrabSnapshots(MaxSnapshots, this.cache) :
        this.LoadFromMemoryStorage();

    if (!snapshots.Any())
    {
        this.Report(LogMessage.SnapshotsAreEmpty);
        return;
    }

    var count = measurements.Count();
    this.Chart.Initialize((count + 1) * 2);

    foreach (var s in snapshots)
    {
        this.Chart.AppendSnapshot(s);
    }
}

这两段代码执行相似。唯一的区别是,在第一种情况下,每个从事该项目的开发人员都使用自己的样式。这使代码不一致,难以阅读且危险。团队成员无法就缩进量达成一致的事实,再加上其中一个人拒绝在每次缩进之后使用花括号这一事实if使代码极易出错:纵观它,我们可能认为第二个if是仅当第一个if为真时才执行,情况并非如此。

在第二种情况下,所有开发人员都遵循相同的标准。其中一些人可能不满意,因为他们更喜欢两个空格的缩进,或者因为它们习惯于以小写字母开头的方法。事实是,这种方式的代码可读性仍然更高,并且如果他们使用任何其他标准,代码仍然会如此。

通过具有严格的统一标准,它使代码更易于阅读。

2.为什么它们的标准比我现在发明的标准要好?

如果世界各地成千上万的开发人员都在使用标准,那就坚持下去。不要自己发明:即使更好,也可以让您更轻松地迁移到全球标准,而不是迁移到成千上万的开发人员那里开始使用您的标准。

示例:在我自己的公司中,我有一个特定的约定来命名数据库中的主键和外键以及索引。这些名称看起来像:

  • [FK for Application: CreatedByApplicationId],
  • [IX for SessionIPAddress: SessionId] 要么
  • [PK for RoleOfPassword: RoleId, PasswordId]。

就我个人而言,我认为这项约定非常出色并且非常明确。为了我。但这完全糟透了。它很烂,因为它是我的,并且因为成千上万的数据库管理员从未使用过它。这意味着:

  • 当我雇用DBA时,他将被迫学习新的惯例,而不是立即开始工作,

  • 我无法按原样在互联网上共享代码:那些看起来很奇怪的名字会打乱那些会阅读我的代码的人,

  • 如果我从外部获取代码以便自己使用,那么我将不得不修改名称以使其统一,

  • 如果有一天我决定使用一些众所周知的标准,我将被迫去修改几百个名字中的每一个。

3.那么,大写呢?

与字段或局部变量相比,属性具有更大的范围或可见性。使属性以大写字母开头,然后将字段和变量(一小部分)朝这个方向发展。

如果考虑使用C#,则此逻辑足够一致。

如果考虑使用Java,则方法以小写字母开头,这不符合逻辑。

因此,没有,没有确切的证据证明该约定比您的约定更好。只是全局使用了一个,而您却没有使用。没有比这更好的了。

在JavaScript中,函数以小写字母开头,除非它们new之前需要一个。否则会更好吗?也许。事实是,多年来,JavaScript开发人员一直使用此标准,而事实并非相反。现在重写每本书并强迫每个开发人员更改样式会有些复杂。


1
至于因为遵循稍有不同的标准而使代码可读性差的部分,我从来没有遇到过这个问题。除非将某人的变量命名为like hookyDookyDoo,否则任何命名或大小写约定都不会损害其可读性。另外,请记住,我并不是说我的约定“更好”,因为它并没有真正为dev表带来任何特殊之处。最后,我不理解您的观点[属性的范围更大...朝这个方向发展]。范围与大小写约定有什么关系?往哪个方向走?
— oscreatingcretin

23
@oscilatingcretin,问题不是您是否遇到过这个问题,而是您的同事是否遇到过。显然他们有,或者他们不会抱怨。
— Karl Bielefeldt

1
关于:您的编辑:您的第一个代码示例仅演示构造不良,易受灾难影响的代码。我的OP并不是关于结构不良,易于灾难的代码。它与第二个示例的代码完全相同,但是大小写约定不同。我编辑了您的第二个代码示例,并按照大小写约定将其发布到了我的OP中。请用您的第一个代码示例替换它。
— 振荡cretin

5
@oscilatingcretin:第一个代码示例演示的不是构造不良的代码,而是演示由每个开发人员遵循自己风格的团队编写的代码。在给定足够的时间(例如五年)的情况下,太多的代码库会发生这种情况。注意:您是否错过了:“事实是这种方式的代码可读性仍然很高,而且如果他们使用的是其他标准,也是如此。” ?
— Arseni Mourzenko 2013年

6
@oscilatingcretin大量研究表明,一致性可以显着减少理解您正在阅读的内容所需的认知努力。对于常规散文而言,拼写不佳,标点符号不佳以及语法不佳都会使某人更难以阅读-无论他们是否有意识地注意到它。代码很难读,但又很难读-遵守“通用标准”(针对您所选择的技术栈)可提高整体一致性,并使神经元腾出精力来专注于代码功能而不是工作方式这个已经写完了。
— Bevan 2013年

10

从技术上讲,这并不重要(或者至少在大多数语言中都没有关系)。

但是,大多数编程社区(无论是围绕一种特定语言形成的世界范围的社区,此类社区的子组,围绕某些流行的库或工具包而形成的组,还是仅单个团队)都已建立了已建立的编码标准。确切的细节是相对不重要的(虽然在很多情况下,一个很好的理由可以为他们制造),什么是重要的是你坚持给他们。

不是因为它们是最好的,而是因为它们是其他所有人使用的;如果您遵守该标准,则您的代码将与最终将要使用的其他大多数代码保持一致-库,队友代码,内置语言。一致的命名是一种强大的生产力武器,因为这意味着当您猜测某物的名称时,通常会猜对。难道file.SaveTo(),File.saveTo(),file.save_to(),FILE.save_to()?命名约定将告诉您。

将您的个人喜好带入您遇到的每种语言中尤其危险,因为首先,每种语言都有其自己的文化,并且命名约定通常是不兼容的。其次,就命名而言,语言之间存在许多细微的差异。

只是一个例子:在C#中,类型和变量位于单独的命名空间中;编译器足够聪明,可以知道区别。但是,在C语言中,两种名称都共享一个名称空间,因此在同一范围内不能具有相同名称的类型和变量。因此,C需要一种命名约定来区分类型和变量,而C#则不能。


因此,确实看起来有些较旧的语言为将来的语言的编码标准铺平了道路(例如您的C / C#示例)。这是最不幸的,因为必须跟踪如何对变量和对象成员进行大小写,这只会增加不必要的复杂性,而无需这样做。
— oscreatingcretin

4
@oscilatingcretin当每个人都使用相同的约定时,它不会增加正在进行的复杂性,该约定成为您所讨论语言的心理模型的一部分,并简化了该语言的使用。这是可证明和可衡量的。
— Mindor先生

我本来是要投票支持您的,但您首先要说没关系,然后您写了几段说明为什么如此重要。如果您在一开始就删除“没关系”,我将投票给您。
— TulainsCórdova13年

10

我很惊讶没有其他人这么说,但是我认为大写差异非常有用,原因之一是:知道变量是否仅在本地范围内,这很好而且很方便。如果该变量是局部变量,那么我不必担心更改它的副作用,例如重构名称。所以我喜欢一个区分类成员与私有类变量与局部变量的约定。

对于现代的Intellisense,这越来越不重要了,但是当我阅读代码以了解应该在哪里找到定义时,它仍然给我一些地标。

几年前我的风格较差时,可能还剩下一些,那时方法不太适合放在一个屏幕上。


我从事的许多项目在其样式指南中都指定了类似的内容。
— anaximander

7

这似乎更像是一个约定问题,而不是您的特定约定。

对于您违反的每项惯例,您只是为其他所有人增加了更多工作。也许在一个完美的世界中,整个公司在整个生命中都使用一种产品……但是,事实并非如此。人们在项目之间跳来跳去,有时跨公司甚至是为了娱乐。代码越随机,处理起来就越困难且成本更高。作为企业所有者或利益相关者,我不想雇用自私自利的开发人员,而不是为了项目的利益。

这归结为专业精神:有时我们需要抛开个人风格,而选择更有效地被大众采用的产品。这鼓励了协作,并消除了本来不应该存在的外部障碍。

根据您的实际约定,CapitalCamelCase通常为类名保留(或在Javascript中为构造函数)。如果我看到一个大写的变量,则有根据的猜测将决定我需要实例化它才能使用它。如果那是错误的,我会很生气,因为该代码没有遵循社区标准。即使使用大多数其他语言,其他人第一次看到它也会立即被误导。我希望代码很明显,不要引起误解。


“如果我看到一个大写的变量,那么有根据的猜测将决定我需要实例化它才能使用它。” 我不明白。看到大写的变量如何使您认为您需要在使用它之前将其实例化?因为它看起来像一个类名?所以,你不知道之间的区别MyClass MyClass = null和class MyClass { }?
— oscreatingcretin

3
是的,我看到了区别。存在该约定是为了避免歧义。var car = new Car();根据我的最后一行-为什么不使其显而易见?
— Adrian Schneider

3
@oscilatingcretin当然是有区别的。但是人脑会从计算机解析器不需要的视觉提示中受益。似乎您在质疑对惯例/标准的需求……这是一个有效的,与您最初提出的问题不同的问题。
— Andres F.

2

“因为应该为属性和void方法保留完全适当的大小写。返回值的局部变量和方法应该使用小写的第一个单词”,因为这是标准约定。

其他程序员现在正在拉起您的代码,并认为这是一个属性,并且它实际上是一个局部变量,这使您的工作更加困难。


1
您是否完整阅读了我的问题?看一下我说过的结尾:NuggetCount all by itself suggests a property or local variable that is simply holding a value. To that last one, one may be tempted to say, "Ah ha! That is the question. Property or variable? WHICH IS IT?" To that, I'd reply with, "Does it really matter?"
— 振荡cretin

8
是的,是的,这很重要,下一个程序员永远不需要思考NuggetCount,您应该能够查看名称并分辨出来。一本好书是“ Clean Code”,您应该能够像读故事一样阅读代码并知道正在发生什么。
— N4TKD

2
@oscilatingcretin我认为您在回答一些与您提出的问题略有不同的问题时所遇到的挫败感证明,如果您违反公认的约定,可能会引起混乱。
— Mindor先生

7
约定带有含义。如果根据约定NuggetCount隐含一个属性,则意味着它的作用域超出了局部变量的范围。这意味着我必须进行更多研究才能确定该范围。我需要确定:进行更改是否有副作用?我可以信任它的值在使用时不会被另一个线程更改吗?nuggetCount表示本地范围,我应该能够假设其整个故事都是本地的。
— Mindor先生

5
@oscilatingcretin是的!究竟!我相信他们写的东西遵循了惯例,并遵循了惯例。我相信他们是团队的一部分,我可以从使用该约定中获益(知道nuggetCount一览无余)。如果他们不这样做,我可能会做您的同事所做的事情:我试图教育一位负责人,下次我不得不浪费时间去不信任他们。通过不遵守约定,他们产生了可读性差,可维护性差的代码。您是否有理由违反惯例?
— Mindor先生,2013年

0

正如其他人所说,没有什么真正的理由,只是不遵循命名约定。如果您可以让整个团队都在同一页面上,则可以节省一些时间。举例来说,我个人开始编写一个编码标准的东西,我们将camelCase用于所有私有变量以及由Val传递的东西,而我们将PascalCase用于公共事物和由Ref传递的东西。

处理诸如protected或Out之类的东西时,线条会变得有点模糊。


-2

语言(包括形式和传统的语言)对于组织您的思想很重要,它对您的思维方式具有影响力。因此,从一种样式过渡到另一种样式只是一种痛苦。

小写和大写符号在Haskell中有很大的语义差异,在Scala中也略有不同,我已经使用了它们。我使用的其他语言在这两种标识符之间没有区别,但是让我以Haskell感知标识符的方式思考比对分散不同语言的思想要容易得多。


-2

对我来说,这归结为期望。

当我阅读大多数代码时,我期望以a开头的任何东西lowerCase都是局部变量或函数(在C#中只是变量)。如果我在中看到一个局部变量ProperCase,我可能会迷迷糊糊一会儿,以为它是类名,属性或其他名称。那会导致我重新阅读代码,并且会惹恼我。

您的情况很可能正在发生这种情况。

另外,仅通过查看第一个字母就能知道变量扮演什么角色,这很方便,并且避免了实例名称和类名称之间的冲突。


-3

局部变量应使用小写字母,以便于键入(速度/无移位键)。大写字母用于通过分隔名称中的单词来提高可读性。具有单字局部变量名称(应该是通用的)的代码可以快速简便地键入。与使用添加下一个字符的下划线相比,对名称中的每个新单词使用大写字母的速度也更快(且空间更少),这也称为驼峰式大小写。


我认为这是一个很好的答案,我不理解不赞成票。这是一个合理的答案-根据OP要求的事实。如果您不赞成投票,请自己解释。整个地方的Shift键很大。考虑一下,几乎在您的代码中键入的每个单词都会启动PascalCase,对于每个单词,您都需要再次按下shift键。如果您想保持简约和有效,则可以删除不必要的Shift键。从逻辑上讲,您希望提高工作效率,这在我站着的位置意味着需要减少按键。为什么要按更多?
— AIon

-3

我在这里同意OP。camelCase看起来不对。我也同意以下事实:这是标准,我们必须坚持相同的标准或制定标准的意义。当不使用为您的方法着色的IDE时,PascalCaps可以用于方法等,而camelCase可以用于您自己的变量等,这是有区别的。

为了解决这个问题,我总是在对象名称之前加上对象的类型。因此,如果它是一个字符串变量,我称之为strMyVariable。如果它是某种对象,则将其称为objMyObject,以此类推。按照标准,它以小写字母开头,看起来不错。


3
在先前的11个答案中,这似乎并没有提供任何实质性的要点和解释
— gnat
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.