95

例如,以这段代码为例:

var person = new Person();

或者对于你 Pythonistas:

person = Person()

我经常被告知这是多么糟糕,但还没有看到这两行代码不道德的例子。对我来说,人就是一个人,试图给它取另一个名字是浪费时间。我想在语法高亮之前的日子里,这将是一件大事。但是现在,很容易将类型名称与变量名称区分开来。哎呀,在SO上很容易看出这里的区别。

还是我缺少什么?如果是这样,如果您能提供一个导致问题的代码示例,将会很有帮助。

4

33 回答 33

94

那些告诉你这不好的人的理由是什么?我一直这样做。这是命名一个类型的单个变量的最简单、最有表现力的方式。如果您需要两个对象,那么您可以使用有意义的形容词作为Person前缀,例如person

fastPerson
slowPerson

否则只是

person

我很好。

于 2009-01-20T13:12:44.387 回答
69

我在方法签名中经常使用这种模式。如果我无法提供替代的描述性名称,那么恕我直言,这没有任何问题。

如果你有两种类型 Person 和 person ,那是非常非常错误的。

于 2009-01-20T13:13:01.983 回答
45

我一直将它用于临时对象引用。我会像原始数据类型的瘟疫一样避免它。

Person person = new Person(); // okay

int Int = 42; // pure evil
于 2009-01-20T13:15:30.450 回答
18

如果有人说这是邪恶的,请问他们这样是否更好:

var abc = new Person();
于 2009-01-20T19:25:57.737 回答
15

如果 Person 是上下文中的一般人,那么“人”是一个非常好的名字。当然,如果 Person 在代码中具有特定的角色,那么最好使用该角色来命名她。

于 2009-01-20T13:18:41.207 回答
9

我想我会因为这样说而被否决,但是......

刚刚经历了一个世纪见证了史诗般的谋杀和贪婪,如果我们能做的最不道德的事情就是命名一个变量,我们程序员真的很幸运。

于 2009-04-29T14:04:26.387 回答
8

我不认为它一定是“坏的”,但显然如果你可以限定它以提供更多上下文,比如它是什么样的人(你只与可能的许多人中的一个打交道),那么其他人就会选择它up可能会更好理解。

于 2009-01-20T13:12:59.533 回答
6

杰森 - 我不确定谁告诉过你这很糟糕。许多作者使用它作为表达(大写)的实例(小写)的标准方式。

我经常使用它,因为我发现小写变量实际上不仅向我传达了这是一个实例,而且还传达了类的名称。

除非有人有相反的有力论据,否则我肯定会继续这样做。

于 2009-01-20T13:14:00.110 回答
6

它被认为不好的原因是,如果您将来需要 2 个人,那么您最终可以得到看起来像这样的代码。

人人 = 新人();

人 person2 = new Person();

那将接近“坏”。但是,在这种情况下,您应该重构您的原始人以区分两者。

至于您的示例,变量名称“person”是对象“Person”的完美描述性名称。因此,它没有任何问题。

于 2009-01-20T14:40:38.607 回答
3

我说出它的名字:如果变量代表一个有 2 条狗的人,就叫它personWith2Dogs。如果变量的范围很短(如循环变量),那么人就可以了。

于 2009-01-20T13:14:22.213 回答
3

我在我的代码中经常使用它,并且不认为它有什么问题。也就是说,我(可能)不会在一个方法中使用它超过一个屏幕,如果有多个 Person 类的实例。绝对不要将它们命名为 person1、person2、person3... 而是使用更具描述性的名称,例如 person_to_del、person_to_ban、person_to_update 等。

于 2009-01-20T16:55:18.790 回答
3

这不是不道德的,但如果您未能激活区分大小写Person,全局搜索会找到两者。person我更喜欢前缀来使全局搜索/替换更容易,但绝对不是匈牙利语或长/复杂的东西。所以,我用...

Person类/类型 aPerson局部变量 thePerson方法参数 myPerson实例变量 ourPerson类变量

在极少数情况下,我可能会p在有很多引用的本地上下文中使用,但这通常只适用于循环索引等。

于 2009-01-20T17:16:14.520 回答
3

这取决于。

如果你有严格的大写风格,所以变量以小写开头(并使用 under_scores 或 camelCase 进行分词),并且类以大写字母开头,那么很明显 person 是一个变量,Person 是一个类,当有人理解这一点时,它们似乎不会在重叠的命名空间中。(类似地,人们几乎不会混淆动词或名词“波兰语”和形容词“波兰语”。)

如果你没有这样的风格,那么你就有两个很容易混淆的名字,而且只是大小写不同。那很糟。

于 2009-01-20T17:20:53.603 回答
2

人们使用的确切论点是什么?

如果他们不允许您使用 person 作为变量名,您可以考虑添加 'a' 前缀。

aPerson = Person()
于 2009-01-20T13:16:18.763 回答
2

我想说的是,每当您创建对象时,您可能都会想到一些特定的用途。单独的类型很少反映这种用途。

因此,如果您想在地址簿应用程序中创建一个新联系人,您可能需要调用变量newContact.

如果您正在对代码进行单元测试以检查Person未设置名称的对象的行为,您可能需要调用它们unnamedPerson或类似的东西。

调用它只是person放弃了使您的代码自我记录的大好机会。

于 2009-01-20T13:16:22.320 回答
2

我认为你正在做的很好。我认为一般来说,达成一致的编码标准很重要。

例如,我将 lowerCamelCase 用于实例、变量,将 UpperCamelCase 用于类等

编码标准应该消除这个问题。

当我看到成功的开源程序时,它们通常具有编码标准

http://drupal.org/coding-standards

http://help.joomla.org/content/view/826/125/

http://wiki.rubyonrails.org/rails/pages/CodingStandards

http://lxr.linux.no/linux/Documentation/CodingStyle

同意编码标准应该是你在这方面的最后一场战斗。

事实上看看维基百科条目(来自http://en.wikipedia.org/wiki/CamelCase

编程和编码风格

编写源代码的编码风格指南(例如,Mesa 编程语言和 Java 编程语言)有时建议使用内部大写来指示单词边界。其中一些指南中包含的建议得到了静态分析工具的支持,这些工具检查源代码的遵守情况。

这些建议通常区分 UpperCamelCase 和 lowerCamelCase,通常指定应为特定类型的实体使用哪种类型:变量、记录字段、方法、过程、类型等。

一种广泛使用的 Java 编码风格规定 UpperCamelCase 用于类,lowerCamelCase 用于实例和方法。 [19] 认识到这种用法,一些 IDE(例如 Eclipse)实现了基于 CamelCase 的快捷方式。例如,在 Eclipse 的内容辅助功能中,仅键入 CamelCase 单词的大写字母将提示任何匹配的类或方法名称(例如,键入“NPE”并激活内容辅助可能会提示“NullPointerException”)。

用于编程的原始匈牙利符号指定“使用类型”(不是数据类型)的小写缩写应作为所有变量名称的前缀,名称的其余部分为 UpperCamelCase;因此,它是 lowerCamelCase 的一种形式。CamelCase 是 Java 和 Amiga 个人计算机文件名的官方约定。

Microsoft .NET 建议将 lowerCamelCase 用于参数和非公共字段,将 UpperCamelCase(又名“Pascal 样式”)用于其他类型的标识符。 [20]

Python 推荐使用 UpperCamelCase 作为类名。[21]

NIEM 注册表要求 XML 数据元素使用 UpperCamelCase,而 XML 属性使用 lowerCamelCase。

在 CamelCase 名称中包含大写缩写(主要是首字母缩写词和首字母缩写词)没有单一约定。方法包括将整个缩写保留为大写(例如在“useHTTPConnection”中)并仅将第一个字母保留为大写(例如在“useHttpConnection”中)。

骆驼案例在计算中绝不是通用的。几种现代编程语言的用户,尤其是 Lisp 和 Forth 系列的用户,几乎总是使用连字符。有时给出的原因包括这样做不需要在大多数键盘上进行切换,单词分开时更易读,并且驼峰式大小写可能根本无法在不区分大小写或大小写折叠的语言中可靠地保留(例如Common Lisp,虽然在技术上是一种区分大小写的语言,但默认情况下将标识符规范化(折叠)为大写)。

于 2009-01-20T16:23:53.203 回答
2

可以做出更有力的论点,即这种方法名称不仅无害,而且可以作为优质代码的指标。

  • 良好代码粒度的指标:如果您的方法简短、用途单一且具有描述性名称,则您不需要变量名称中的大量信息。如果你有很长的方法来做很多事情并且需要跟踪很多上下文和状态,那么你的变量名需要更具描述性。

  • 通用计算被推入通用方法的指标:如果您在业务方法中对数据结构进行中间操作,例如必须对用户数组进行重复数据删除,则必须在范围内包含变量用users[]和之类的名字deduplicatedUsers[]。如果将重复数据删除移动到实用程序方法,则可以调用方法Utils.dedup(array),并且可以调用重复数据删除的数组deduplicatedArray或仅调用result.

  • Java 反编译器经常使用类似的方案来命名局部变量(实例和类变量通常在字节码中可用,但局部变量不可用),结果比您预期的更具可读性,实际上通常比原始来源。

  • 请参阅 Larry Wall 的“局部歧义是可以的”原则 - http://www.wall.org/~larry/natural.html

于 2009-01-20T18:24:00.827 回答
2

仅当您使用 VB6 编程时。在这种情况下,你的行为是非法的,但不是不道德的。

于 2009-09-14T06:29:30.637 回答
1

我也这样做,我也不明白为什么它应该是“不道德的”。虽然我可以理解它“可能”有时会令人困惑,但今天我们有带有智能感知和语法突出显示的 IDE,这将确保(如果你犯了错误并引用你的变量而不是你的类,反之亦然)你会很快就能看到你的错误。我们也有编译器。:)

于 2009-01-20T13:14:25.833 回答
1

我也认为这种做法没有任何问题。只要该类只有一个变量,就容易写易读。Imo,这甚至适用于基本的文本编辑器。我个人不记得有人说这很糟糕,甚至是不道德的。继续这样做:)

于 2009-01-20T13:21:26.223 回答
1

我认为您可能想到的“规则”更多地适用于原始类型,以及类名使变量名不佳的类。

例如,如果您正在处理计算在线商店中特定商品的成本,则以下代码不是很好的形式:

Decimal _decimal = item.BaseCost + item.Tax;

相反,建议使用更具描述性的名称,例如“_total”或“_cost”。

于 2009-01-20T13:33:16.310 回答
1

我发现这种事情的唯一问题是,如果您希望私有成员和公共财产具有相同的名称。

如果这些仅在大小写上有所不同,那么它在区分大小写的语言(如 C#)中可以正常工作,但在 VB.NET 中则不行。

所以,例如,在 VB 中,我会写

Private _name As String

Public Property Name() As String
    Get
        Return _name
    End Get
    Set(ByVal Value As String)
        _name = Value
    End Set
End Property

我会在 C# 中做同样的事情,所以从一个到另一个的翻译是无痛的。它也减少了出错的可能性,因为它很容易被误读,或者实际上是错误类型的单词,只是大小写不同。

于 2009-01-20T13:41:44.453 回答
1

我经常用Person person = new Person()自己。常用于 Java/C#。

虽然我昨天最终想知道为什么

private enum DataType {NEW, OLD}

在 C# 中不起作用...

尤其是看看如何在 C# 中随意使用String, string, Double, double,... 。

于 2009-01-20T13:42:37.367 回答
1

这不是不道德的,但是如果您对变量的最佳名称是类型的名称,则有问题,或者您只是在进行概念证明或类似的事情。对我来说,变量名必须指的是业务上下文中的含义,而不是编程语言。理解代码会更加困难。

于 2009-01-20T13:52:32.870 回答
1
Person person = new Person()

在我的书中很好。

当你有以下情况时,它变得可怕:

string Person;
string person;

很容易混淆2。

于 2009-01-20T14:45:03.997 回答
1

除了不符合我们的编码标准外,向我表达的内容是避免在其他人阅读我的代码时增加混乱。我个人认为没有问题,只要意思清楚。

至于 CLR 类型(int、string 等),您可以使用 String 或 string(等)来声明类型,所以我会避免使用类似

int Int = 0;
string String = "hi there";
于 2009-01-20T15:43:00.027 回答
1

使大写成为唯一的区别是危险的……继续为一个大项目这样做,我保证你会遇到你似乎无法找到的奇怪错误。

像上面这样的 fastPerson/slowPerson 很好......它们是描述性的,并且与变量类型名称有区别......但是来吧,调用 int “Int” 会很懒惰。

于 2009-01-20T15:45:53.797 回答
1

我会说它绝不是不道德的——它实际上只是你的基线变量名。如果你想不出一个更好的名字,那么在它的类型之后命名是一个很好的默认值。(适用于复杂类型- 对于内置类型它是邪恶的)而且很多时候真的没有更好的名字,因为你没有'对变量一无所知。喜欢这个方法

void SaveToDatabase(Person person) {...}

关于你可以合理地称之为人的唯一其他东西是person_to_save或类似的东西似乎是多余的。

但是在很多情况下,您可以通过将 person 替换为更具描述性的名称来提高代码的可读性。例如,这描述性较差

void AddToAccount(Account account, Person person)  {...}

比这个

void AddToAccount(Account account, Person dependent)  {...}

但是请,请 - 请不要在类型名称前加上“a”或“t”。IE aPerson 代表“一个人”或 tPerson 代表“那个人”。它过于复杂,如果有任何价值,也不会增加太多。另外,你开始用一堆以 a 或 t 开头的变量污染你的范围,这可以最小化智能感知的价值。

于 2009-09-14T07:13:39.220 回答
0

我不会说这很可怕。在这种情况下,我通常在变量名称前加上“a”,以表明它是该类型的单个实例,所以我会这样做

Person aPerson = new Person();

我认为它使代码阅读更自然。

于 2009-01-20T14:31:57.550 回答
0

根据其他人指出的警告(为了方便起见,在这里总结一下),它绝对没有错:不使用原始类型,如果稍后添加另一个实例,则重构原始实例,不使用 char-case 来区分类名等。

我的经验法则?代码中的语句应该读起来像简单的英语句子。

人人 = 新人();

员工员工 = person.getRole(EMPLOYEE);

父父 = person.getRole(PARENT);

人.getFullName();

雇员.getSalary();

parent.getChildren();

父.getFullName(); // 假设装饰器模式在起作用

if (person.hasRole(EMPLOYEE)) {

  ...

}

等等。

如果变量的范围有限(例如,封装方法是 10-15 行),我什至可以使用 'p' 而不是 'person'。尝试在脑海中保留上下文时,较短的变量名称不会分散注意力。避免无缘无故的前缀,例如“a”或(不寒而栗)匈牙利符号及其分支。(请注意,在适当的上下文中使用此类前缀 - C++ / COM / ATL / Win32 API 代码等,它有助于保持分配/类型转换的直接性)。

我的两个(!)位:-)

于 2010-07-06T13:00:06.283 回答
0

不仅没问题,而且合理。

微软甚至提出了类似的建议(这可能会让一些人感到惊讶),将属性命名为与其类型相同。我知道这不是一回事,但它可能会打开你的想法。

http://msdn.microsoft.com/en-us/library/fzcth91k(VS.71).aspx

于 2010-07-13T19:24:49.973 回答
0

不,将其命名为不同的名称也不错,例如

Person clerk = new Person();
Person manager = new Person();

不好的是编造如下无意义的名称:

Person xyz = new Person(); 
于 2010-12-04T05:09:27.340 回答
-3

不道德...不。比重构更困难,...是的。

试试“_person”

于 2009-01-20T13:14:07.863 回答