故意拼写错误以避免保留字


45

我经常看到这样的代码,其中包含常见单词的故意拼写错误,无论好坏,这些单词已成为保留单词:

  • klassclazzClass clazz = ThisClass.class
  • kount用于计数在SQL:count(*) AS kount

我个人认为这会降低可读性。在我自己的实践中,我发现没有太多案例无法使用更好的名称- itemClassrecordTotal

JavaDocs for Class中的示例在参数中显示了这一点:

 public <U> Class<? extends U> asSubclass(Class<U> clazz)

这是否显示合理的用例?


9
记录一下:在Python中,cls是连续的实际类(用class关键字声明的那些,并且所有都是其实例)的变量/自变量的通用名称(实际上是一个惯用名称)。

14
你不喜欢typedef char ínt吗?
Jeff

14
@muntoo你是对的。我也收到的编译器错误iñt。我有实现世界统治的计划。
杰夫

1
我已经违反了这条规则...现在我感到羞耻。
jmq 2011年

3
不要这样 老实说,我以前从未见过,如果这样做,我会立即重命名。如果您必须使用非描述性的变量名(Class c),请缩写。
科迪·格雷

Answers:


63

恕我直言,这是一个非常糟糕的主意。保留字被保留是有原因的,这样做确实会降低可读性。

我也完全同意你的第二点。命名变量class(即使您可以做到)也和命名它tmp或一样糟糕a。什么样的课?一类什么?名称应具有描述性。


15
“保留字是出于某种原因保留的” <-这。(具有讽刺意味的是,这是保留的。)
trycatch 2011年

16
+1是因为您是对的。但是,如果您正在编写教室调度软件之类的东西,则类可能是合法的变量或类名称……
CaffGeek 2011年

8
嗯 “ 保留字保留是有原因的 ”,这就是语言设计者很懒。在相当多的复杂语言中,单词仅保留在使用它们的特定位置。但是Ritchie在需要C语言的轻量级编译器时就开始了这种趋势,并且大多数语言设计师都从那里学到了它。
罗斯·帕特森

14
不,罗斯,这是因为程序员(和一般的读者)对事物具有合理的明确含义的期望(这就是为什么学习外语通常会如此困难,所有事物都有双重含义或与您所提出的语言不同的含义的原因在童年时代就不会注意到这些歧义,因为它们是您文化遗产的一部分。
jwenting

3
@AlexanderMorou Nope,也没有大多数语言设计师,他们只是从别人的设计开始。但是看看Algol,Fortran,PL / I,Rexx和其他不基于C的语言,您会发现没有保留字的语法肯定是可能的,只是难度更大。Ritchie有一个很好的理由-Unix人士认为每个按键都很重要,而在PDP-11上,每个CPU周期都很重要。今天?没那么多。
罗斯·帕特森

21

Python的样式指南专门指出了这个问题,并提出了以下建议:

如果您的公共属性名称与保留关键字冲突,请在属性名称后附加一个下划线。这比缩写或拼写错误更可取。

假设它与特定语言的语义没有冲突,这似乎是一条很好的通用规则。


7
我觉得这是来自样式指南的不佳建议。如果您的属性名称非常接近关键字,则应该找到一个更好的名称。只需在结尾加上下划线并不会增加任何意义,这很可能会使下一个读取代码的人感到困惑。
韦恩·约翰斯顿

18
@Wayne:当union关键字是关键字时(如在C中),您将如何在联合查找结构中命名联合操作?您是否foo只是因为它看起来不像它而将其称为union
Fred Foo

OTOH,cls是类方法的标准参数名称。同样,例如在Django中,对象具有.id属性,这当然与id内置函数冲突。
vartec

1
@GoloRoden我从未听说过有人说他们在计算工会时将两套武器“联合起来”。它只是行话的一部分。“合并”会更好,但是一种merge方法仍需要明确说明其实现联合的文档,并且纯粹出于技术原因而被重命名。
福雷

2
@GoloRoden根据Merriam-Webster的说法,它不是动词,但请参见此答案
maaartinus

18

代码气味。

string stringVariable = "";

上面的代码告诉我有关变量预期用途的任何信息。

class Klass

同样的问题

string UserNameString = "bmackey"

上面的代码不应要求在变量名后附加关键字字符串。如果您发现自己需要通过变量名来标识类型,则您的代码太长。冷凝重构。


它没有告诉您任何信息,因为它不是“代码”,它是一个隔离的变量声明。一个“班级”或“桶”可能很好地告诉您所有您需要知道的。例如,通用方法可以接收Class<T>参数,这很有意义。因此,我不同意这是一种代码味道。
Andres F.

5

就个人而言,我认为这对于您的代码样式来说是一个非常有效的选择。

它们是保留字,因此编译器不必确定您的意思是语言机制还是变量。考虑到这一点,这意味着他们期望人们需要一个像保留字这样的变量。

通过与JDK 1.6 R21捆绑在一起的源代码,我发现917个“ clazz”出现。显然,他们认为这是可以接受的风格。

您的团队对此感觉如何?如果您认为这很糟糕,但是团队中的其他9个人认为这很好,那么您就必须硬着头皮接受它。只要能就什么可以,什么不可以进行交流,并且提出的问题就可以了。

您的团队对代码风格的感觉比我或其他任何人的看法更重要。这以及您可能拥有的其他任何代码样式决策都适用。


1
是的,但是最终您的团队会改变。许多年以后,会有一个可怜的家伙看着您的代码,里面充满了各种技巧和提示,并说“ WTF!”。
MrFox

4
如果您同时使用两者klassclazz那将是一件坏事。您需要保持一致,以便他们只需学习一次。理想情况下,这也在团队风格指南中阐明,所以这并不令人感到意外。
corsiKa 2013年

代码不仅是为团队中的人员编写的,还为世界其他地方编写。当您的团队都在穿越悬崖的公共汽车上时,其他人将开始阅读代码。使用完整,简洁地描述变量是什么的名称,而不是变量的表示方式。
罗布K

1
不,根本不行。随着时间的推移,您的团队离轮换成员的可能性越来越大。您可以计划一个人被公交车撞到,但是您不能计划整个团队都被公交车撞到。大多数代码是为可能需要阅读的十几个人编写的,其中一半是在代码审查期间编写的。
2015年

4

故意使用拼写错误来避免保留字是一个坏主意。

  • 拼写错误很难与正确的拼写区别开,因此它们会使代码更难阅读。

  • 拼写错误很难记住,因此在代码中可能会出现几种不一致的拼写错误,这使得代码更难编写和阅读。

  • 保留字是指用于解决问题的语言,而不是问题本身。变量名称应指向与问题相关的概念。

因此,最好选择一个替代性的描述性名称,或者如果不存在令人满意的替代性名称,则使保留字符合以下条件

public static Method findBenchmarkMethod(BenchmarkRecord benchmark) {
    Class<?> benchmarkedClass = ClassUtils.loadClass(benchmark.generatedClass());
    return findBenchmarkMethod(benchmarkedClass, benchmark.generatedMethod());
}

3

Class clazz闻起来像是“我没有费力去想出一个好名字”。变量总是代表某种东西,一个好名字来描述它。我拒绝想象clazz在任何情况下都可能是最好的名字。它是对类的引用-> class_reference,是对类对象的副本-> class_copy,等等。可能还会删除“ class”,仅使用描述性词,例如

java.lang.SecurityManager.checkMemberAccess(Class<?> clazz, int which)
Parameters
    clazz -- the class that reflection is to be performed on.

这里clazz是要执行检查的目标类,因此

checkMemberAccess(Class<?> target, int which)

比clazz更能描述该参数的用途。


恕我直言,这不是更好,您可以将其命名为“ classToBeAccessed”或其他名称,但任何更具描述性的名称都只是显而易见。仅当长名称提供有用的信息时,我才喜欢长名称。
maaartinus 2014年

1
classToBeAccessed确实是个好名字(classToBeChecked也许会更好)。
hlovdal 2014年

1

如果他们使用变量的保留名称,则该变量的名称不正确。即使它是合法名称,例如教室软件的Class。

命名不佳的变量是思想欠佳或代码随意的迹象-提防您维护的软件中的其他陷阱。


0

我认为,如果谨慎且一致地使用故意拼写错误或缩写是一个好主意。

在Java中考虑:

class X { public X() { } }
X x = new X();
x.getClass;  // Wha?  How does "get" help anything?
x.class;     // Best, but requires more lexer/parser work
x.klass;     // At least as good as getClass
x.clazz;     // Same

使用拼写错误的地方是保留字显然是该工作的最佳字。有两个地方不建议您使用拼写错误。

  1. 你不会想起一个好名字
  2. 您只需要一个虚拟变量,并且不需要描述性名称

在第一种情况下,很明显懒惰很少是创建高质量代码的好策略。在第二种情况下,选择一个非常短的变量。那是数学家一直在做的事情,程序员是在做索引的事情。如果确实只是一个虚拟变量,没有理由将自己限制在索引上:

boolean isMyName(String testName) { return myName.equals(testName); }
boolean isMyName(String s) { return myName.equals(s); }

Date nextMeeting(Klass klass) { return /* something */ }
Date nextMeeting(Klass k) { return /* something */ }

当方法或代码的结构告诉您必须存在的内容时,使用简短的变量名不会丢失任何内容。


2
对不起,我不同意。nextMeeting到底如何工作?逻辑是模糊的。您强迫我每次阅读代码时都要查找Klass的定义,因为名称毫无意义。相反,如果您有nextMeeting(MeetingRoom meetingRoom),则我将少读一个类(玻璃?clazz?)定义,从而提高工作效率。获得的代码比编写的更多。
MrFox

@suslik- nextMeeting(MeetingRoom r)足够了。什么meetingRoom让您到达那里?如果ti是nextMeeting(int meetingRoom)我所理解的,但我的意思是在信息可以从其他来源获得的情况下,使用简短的变量名
Rex Kerr 2013年

我的帖子更多地是关于代码库中Klass的存在。我有时会同意使用短的变量名,但是如果您的方法变长并且您必须继续努力以确保“ r”是MeetingRoom,那也不好。我很好奇MeetingRoom的缺点是什么?水平空间?输入时间太长?
MrFox 2013年

@suslik-是的,您失去了带有长变量名的水平上下文。使用长方法会丢失垂直上下文,因此最好尝试避免这些情况(但是无论如何我都同意,您可能希望变量名可以更好地提醒您)。 有保留字的时候Klass是另一种选择。当原始拼写可用时,我不建议使用拼写错误!
Rex Kerr 2013年

0

我已经看到了Class klass在实际使用Class类的实例进行反射时的合法用法。


2
问题不是在任何情况下都存在实例,而是是否应该使用该拼写,还是使用更具描述性的名称(例如userClass或其他选项)。
妮可,

2
在这种情况下,我宁愿classInstanceklass
Konrad Morawski 2014年

2
@KonradMorawski:但是您使用的所有对象都是实例,因此classInstance非常多余。而且,我可以想象类似的东西class klass; Object classInstance = klass.newInstance;
maaartinus 2014年

0

我经常看到这样的代码,其中包含常见单词的故意拼写错误,无论好坏,这些单词已成为保留单词:

班级的克拉斯或克拉兹:类别clazz = ThisClass.class

SQL中的计数的kount:count(*)AS kount

我个人认为这会降低可读性。在我自己的实践中,我发现没有太多情况无法使用更好的名称-itemClass或recordTotal。

但是,这种情况太普遍了,我不禁想知道我是否是唯一的一个?任何人都可以从受尊敬的程序员那里获得任何建议甚至更好的引用建议吗?

对于局部变量和形式参数,这无关紧要。

只要没有故意误导或烦人的干扰,任何名称都可以。在您的示例中:

public static Method findBenchmarkMethod(BenchmarkRecord benchmark) {
    Class<?> clazz = ClassUtils.loadClass(benchmark.generatedClass());
    return findBenchmarkMethod(clazz, benchmark.generatedMethod());
}

单个局部变量是“ clazz”还是“ klass”或“ cls”还是仅仅是“ c”都没有关系。我可能只是内联表达式:

return findBenchmarkMethod(ClassUtils.loadClass(benchmark.generatedClass()),
                           benchmark.generatedMethod());

变量名称的长度应与变量的范围有关。对于使用短方法的局部变量(它们都应该短),非常短的名称就可以了。


您的内联看起来不正确ClassUtils.loadClass(benchmark.generatedClass())=> benchmark.generatedClass()- ClassUtils.loadClass一路上迷路
2014年

0

我认为拼写错误始终是个坏主意。这对您的读者来说不是很好。我想知道的是,当我看到这个词时我是否错过了什么klass。(他们的意思是class,还是海盗?)至少对我而言,我认识到的所有拼写错误都很令人讨厌。

在极少数情况下,保留字实际上是唯一有关变量的重要信息,我将使用以下替代方法:

  • 如果是函数参数,请使用aClass代替class

  • 如果是局部变量或成员变量,请使用myClass代替class

  • 如果是访问器,请使用getClass()代替class()

当然,添加的前缀是毫无意义的,因此,只能将其用作最后的手段。但是至少它不会干扰读者的心理分析器,并且这是避免保留字的一种故障保护方法。


0

创造性拼写的好处之一是更好的搜索能力。我认为,对唯一的事物进行完整的代码搜索比对普通的单词进行搜索要容易得多,在普通的单词中,您经常会发现所有错误的事物,其中有1000多个错误。例如,我曾经拥有kzpg.com。谷歌现在,您只会看到一些点击。它是唯一的,因此非常容易找到。

但是从某种程度上来说,我认为这个问题不仅仅是实质性的观点。我个人是在Forth上长大的,而这全都是关于单词的,其中很多都是单词。一个人学会了变得非常有创造力,以拯救自己的手指。最后,我的来源库中大约有640,000个字符。因此,保持简短对完成工作很重要。


现在该链接已断开。
彼得·莫滕森
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.