命名:为什么在 C++/Java 中命名常量应该全部大写?
我知道,对于 C++ 和 Java 来说,这是一个完善的命名约定,常量应全部大写,并用下划线分隔单词。 像这样(Java示例):
public final static Color BACKGROUND_COLOR = Color.WHITE;
public final static Color TEXT_COLOR = Color.BLACK;
这个命名约定很容易理解和遵循,但我问自己,为什么选择这个命名约定而不是变量的正常命名约定:
public final static Color backgroundColor = COLOR.WHITE;
public final static Color textColor = COLOR.BLACK;
似乎没有必要改变常量的外观。 如果我们想给它们赋值,编译器无论如何都会阻止这种情况。 实际上,如果稍后将常量更改为适当的变量(因为例如颜色可以配置),它会产生问题。
那么命名常量全部大写的最终原因是什么? 历史原因?
I know, that for C++ and Java it is a well established naming convention, that constants should be written all uppercase, with underscores to separate words. Like this (Java-example):
public final static Color BACKGROUND_COLOR = Color.WHITE;
public final static Color TEXT_COLOR = Color.BLACK;
This naming convention is easy to understand and to follow, but I ask myself, why choose this naming convention over the normal naming-convention for variables:
public final static Color backgroundColor = COLOR.WHITE;
public final static Color textColor = COLOR.BLACK;
Theres seems to be no need to change the look of constants. If we want to assign a value to them, the compiler will prevent this anyways. Actually it makes problems, if later the constant will be changed into a proper variable (because the colors get configurable for instance).
So what's the ultimate reason to write named constants all uppercase? Historical reasons?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
我认为这不是一个技术问题,而是一个心理问题。 命名约定不是让编译器处理的(计算机并不真正介意名称),而是让浏览代码的程序员以尽可能少的努力获得尽可能多的信息。
使用不同的命名约定可以清楚地告诉读者,您正在阅读的内容是在编译时固定的,您不需要跟踪代码来确定值在哪里以及如何到达那里。
I think it is not a technical problem but rather a psychological one. Naming conventions are not for the compiler to process (the computer does not really mind names) but rather for the programmer that is browsing the code to have as much information as possible with as little effort as required.
Using a different naming convention is clearly telling the reader that what you are reading is something that is FIXED at compile time and you don't need to follow through code to determine where and how the value got there.
我相信在 C++ 中,这是从使用预处理器 #define 常量值的时代延续下来的约定。 当时,这样做是为了避免预处理器践踏您的源代码,因为 C 函数和变量名称的通常约定会使它们混合大小写或小写。
从 C++ 的角度来看,我想说将常量全部大写是一个坏主意。 因此,我不得不调试多个构建问题 - 请记住,C++ 预处理器对命名空间和命名范围一无所知,并且会很乐意替换它认为合适的内容,即使它相当不合适。
I believe in C++ it's a convention carried over from the days of using the preprocessor to #define constant values. Back then, it was done to avoid having the preprocessor trample all over your source code, as the usual conventions for C function and variable names would make them mixed case or lower case.
From a C++ point of view, I would say that it's a bad idea to make your constants all-uppercase. I've had to debug more than one build problem because of this - remember that the C++ preprocessor does know nothing about namespaces and naming scope and will happily substitute what it thinks is appropriate even though it is rather inappropriate.
我可以想象,最初,在 C 时代,人们会使用预处理器象征性地实现“常量”:
这样的“常量”只是美化的文字,因此它们的行为并不完全像变量。 例如,您不能获取这样一个“常量”的地址:
因此,让它们“脱颖而出”是有意义的,因为它们实际上不仅仅是“您无法更改的变量”。
I can imagine that initially, back in the C days, people would implement "constants" symbolically, using the pre-processor:
Such "constants" are just prettified literals, and as such they don't behave quite as variables. You can't, for example, take the adress of such a "constant":
For this reason, it makes sense to have them "stand out", as they're really not just "variables you can't change".
如果我知道某件事是常量,我可以多次引用它并知道它不会改变。 换句话说,我知道:
与:
有时了解这一点很有用。 就我个人而言,我更喜欢 .NET 命名约定,即对常量(和方法)使用 Pascal 大小写:
我不太喜欢大写字母大小写……但我确实喜欢常量显然是常量。
If I know something is a constant, I can refer to it multiple times and know it won't change. In other words, I know that:
is the same as:
That can be useful to know sometimes. Personally I prefer the .NET naming convention, which is to use Pascal case for constants (and methods):
I'm not a big fan of shouty case... but I do like constants being obviously constants.
此引用来自 C++ 核心指南总和这一切。
This quote from C++ Core Guidelines sums it all.
在 C(然后是 C++)中,用预处理器 #define 指令定义的符号全部用大写字母编写,向开发人员发出响亮的信号,表明代码并不像看起来那样,并且不要将其视为正常符号。 常量最初并不存在于 K&RC 中(尽管后来从 C++ 中带回了 const),因此开发人员使用了 #define 来代替,因此有了上限。
由于某种原因,这在 Java 中被扭曲为“常量是大写的”,因此是当前误导的(IMO)约定。
In C (and then C++), symbols that were defined with the preprocessor
#define
directive were written all in caps as a loud signal to developers that the code was not as it seemed and to not treat as a normal symbol. Constants did not initially exist in K&R C (althoughconst
was brought back from C++ later) so developers used#define
instead, hence the caps.For some reason, this got twisted into Java as "constants are caps", hence the current misguided (IMO) convention.
我认为大写常量是 C 的不良遗产。背后的逻辑与使用下划线作为私有成员的前缀时相同。 这是技术性的东西,已经通过 Java 关键字(如
private
)或(对于常量)static final
等 Java 关键字来表达。I think uppercase constants are a bad heritage from C. The logic behind is the same as when using underscores as prefixes for private members. This is technical stuff which is already expressed by Java keywords like
private
or, in the case of constants,static final
.实际上,大多数 C++ 命名指南(包括 ISO、Boost、Sutter & Stroustrup 和 Google)强烈反对使用全部大写的命名常量。 这是因为宏也使用全部大写,并且它们可能散布在头文件中,可能会产生奇怪的行为。 无论如何,人们仍然使用全部大写,因为他们从旧的 C/K&R 或旧的遗留代码中学习。 然而,在现代 C++ 新代码中,您应该避免对除宏之外的任何内容使用全部大写。
我对为什么全部大写存在的宠物理论是,在非常旧的机器上,代码是使用数字键盘直接在机器代码中输入的。 当汇编语言出现时,它只使用全部大写,因为当时的键盘尚未标准化,并且某些键盘受到限制,例如,使用与功能手机相同的数字键盘来输入字母。 这后来被延续到许多早期语言,比如 BASIC,它涵盖了一切。 当实际的终端可用并且键盘开始标准化时,人们开始毫无保留地使用混合大小写,并且所有大写字母都被保留给那些很少出现的东西,例如与函数和变量相比的常量。
大多数 C++ 指南现在都同意使用“k”作为常量的前缀,后跟带有下划线或驼峰命名法的名称。 我个人更喜欢 kCameCase,因为它可以轻松区分使用下划线命名的变量。
Actually most C++ naming guidelines (including ISO, Boost, Sutter & Stroustrup and Google) strongly discourages naming constants with all caps. This is because macros also use all caps and they can be littered all over in header files potentially creating strange behaviors. People still use all caps anyway because they learn from old C/K&R or old legacy code. However in Modern C++ new code you should avoid using all caps for anything except macros.
My pet theory for why all caps exists at all is that on very old machines, code was being entered directly in machine code using numeric keypads. When assembly language arrived on the scene, it only used all caps because keyboard at that time weren't standardized and some keyboards were limited ,for example, using same numeric keypads to enter alphabets like in feature phones. This got then carried over to many early languages like BASIC which is all caps everything. When actual terminals became available and keyboards started to get standardized, people started using mixed cases without reservations and all caps got reserved for something that is rare in occurrence like constants compared to functions and variables.
Most C++ guidelines now agree on using "k" as prefix for constant followed by name with either underscore or CamelCase. I personally prefer kCameCase because it easily allows to distinguish from variables which are named with under_scores.
基本上,当人们爱上 C、C++ 和 C++ 的时候。 Java 要么是新的,要么尚未创建,人们对预处理器常量名称使用全部大写,以表明它们实际上不是变量。
考虑到这是在 C 中定义真正常量的唯一真正方法(如果您知道如何更改 const 变量,仍然是可能的),这样的预处理器常量仅被视为常量,因此全大写名称的含义从预处理器常量转变为一般的简单常量。 这随后被延续到后来的语言中,成为标准的“consts = 大写字母”实践。
然而,其他语言有自己的首选样式(例如,C# 和 .NET 更喜欢 PascalCase),因此如果有首选样式,通常最好使用首选样式。
Basically, back when people were in love with C, and C++ & Java were either new or not yet created, people used all caps for preprocessor constant names, to indicate that they weren't actually variables.
Considering that this was the only real way to define a true constant in C (it's still possible to change
const
variables if you know how), preprocessor constants like that were just seen as constants, and as such the meaning of all-caps names shifted from preprocessor constants to simply constants in general. This then carried over into later languages, becoming the standard "consts = capitals" practice.Other languages have their own preferred style, however (for example, C# & .NET prefer PascalCase), so it's generally best to use the preferred style if there is one.
使用大写常量,长公式更容易阅读,您不必猜测哪些元素可以变化,哪些元素不能变化。 这当然只是一种约定,但却很有帮助。
With uppercase constants long formulas are much easier to read, you don't have to guess which element can vary and which can not. It's of course only a convention, but helpful one.
这是一种解决方法,可以解决您的开发工具无法以方便的方式发现标识符属性的情况。
很像匈牙利表示法。
当您的 IDE 变得更好时,您将不再需要任何命名约定,而是需要规定名称是有关标识符含义的综合信息的约定。
即使这可能会发展:为什么不创建一个编程系统,您只需创建标识符,并向其添加属性,例如“简要描述”,“类型”,......当可以以方便的方式完成此操作的工具出现时,我' “意向编程”是一个提示。
It's a workaround for your development tools not being able to spot the properties of an identifier in a convenient way.
Much like Hungarian notation.
When your IDE gets better, you won't need any naming convention but the one that dictates that a name is comprehensive information on what an identifier means.
Even that may evolve: why not create a programming system where you just create identifiers, and add properties to it like "brief description", "type", ... When the tool arrives that can do this in a convenient way, I'm in. "Intentional Programming" is a hint.
也许你是对的。 计算机和编译器(尤其是)没有今天那么快。
Joel Spolsky 在他的一篇文章中提到他对新版本的编译时间印象深刻涡轮帕斯卡。
我记得在 PC XT 10MHz 上的 Turbo Pascal 5.0 中编译不太大的程序 (10-20KLOC) 需要大约 20 分钟......
我想等待编译来检测错误是不可接受的。
这样的约定有助于避免在损坏的编译过程中出现错误和浪费时间。
Probably you are right. Computers and compilers (especially) were not so fast as today.
Joel Spolsky mentioned in one of his essays how impressed he was with compilation time of new version of Turbo Pascal.
I remember when compilation of not too big program (10-20KLOC) with overlays in Turbo Pascal 5.0 on PC XT 10MHz took about 20 minutes...
I suppose that waiting for compilation to detect error was not acceptable.
And convention like that helps to avoid errors and wasted time during broken compilation.
编程时,创建人类可以理解的代码非常重要。 命名约定有助于做到这一点。 当查看您没有编写的代码时,这是最好的,并且使代码更易于维护,因为它很容易与常量和变量区分开。
When programming, it is important to create code that is understandable by humans. Having naming conventions helps to do this. This is best when looking at code that you didn't write and makes the code more maintainable because it is easy to distinguish from constants and variables.
编码转换是为了提高可读性。 您不必使用字母。 例如,Java 允许 $ 符号。
您也可以对变量进行编号,但这并不意味着这是一个好主意。 ;)
Coding conversions are to improve readability. You don't have to use letters. Java allows $ symbol for example.
You could number your variables too, but that doesn't mean its a good idea. ;)
这纯粹是为了帮助程序员一目了然地了解他或她所看到的内容。它有助于了解正在使用的常量,以便无论您如何引用该值都不会改变它。
关于编译器方面的事情并没有真正的原因。 命名约定纯粹是约定,而不是真正的技术限制。
This is purely to help the programmer understand what he or she is looking at from a glance. It helps to know that a constant is being used so that the value won't change no matter how you refer to it.
There isn't really a reason regarding the compiler side of things. Naming conventions are purely that, conventions, not really technical restrictions.