下划线命名和驼峰命名

因为 bgfx 的 idl 在之前的其它部分采用的是驼峰命名法,然后生成 C 接口的时候再转换为下划线命名。所以自然而然的,就想继续采用驼峰命名法。
但稍有不同的是,bgfx 目前的宏定义只有 C 风格的版本,也就是下划线命名的。只是计划在未来可以生成出一半采用驼峰命名法的 C++ 常量版本。在没有 idl 时,维护两个版本成本太高,故而只有 C 风格的宏一个版本。
所以,这次并没有两个版本的命名可以参照。
我在使用驼峰命名这一系列宏的时候,发现了驼峰命名法对于带数字的名称表示其实是有歧义的。可以说是一种缺陷,我之前自己的项目以 C 语言居多,一贯使用下划线命名法,没有意识到这点。这个问题有点意思,值得记录一下。
在下划线命名法里,单词间隔是非常明确的,用一个独立的字符分割。但是英文字母本来就区分大小写,似乎可以用大写字母来间隔单词,这样多单词连写在一起时更为紧凑,驼峰命名法看起来似乎更好看一些。
但是,有两种例外情况。
第一,是多个单词的首字母连起来的缩写,习惯上我们使用全大写表示。例如 RGB ,是 RedGreenBlue 的缩写,但是我们几乎不会用全称。那么 RGB 到底应该是一个单词还是三个单词呢?

即,如果把含有 RGB 的驼峰命名的词转换为下划线命名,到底应该是 r_g_b
还是保留为 rgb 或是 RGB 。我认为一定不会是 r_g_b
,因为它已经是缩写了,不应该再用下划线间隔开。至于用小写 rgb 还是大写 RGB 可以商榷。
所以,对于连在一起的大写字母,我倾向于它们是一个单词。
但是缩写 RGB 和下一个单词连写的时候就会造成麻烦。比如 RGBBitmap 怎么分词?这样就需要再加一条规则,小写字母串一定和它之前的一个大写字母是一个词。
当然,还有一种做法是把缩写词的后几个字母也小写,把 RGB 写作 Rgb 。这些也很明确,只是不太符合日常习惯。
第二,是数字怎么处理。数字没有大小写之分,所以不方便断词。不过通常数字也不会单独成词,例如 3d ,这明显是一个词。
一开始,我想把数字全部当作是大写字母,这样方便用正则表达式转换。比如 D3D12 就可以看成是全大写字母,很自然的把它分成一个词。只是数字不可以单独和后面的小写字母串放在一起成词。

但我发现了 Int32 这种词。其实我们在下划线命名中,习惯上是不会写作 int_32
的。也就是说 int32 其实是一个词而不是两个。我们无法依靠数字前面是小写字母还是大写字母来决定如何分词,比如 Create3d 这里的 3d 和 Create 就是要断开的。
最终,我在 bgfxidl 项目中采用了下划线和驼峰混用的表示方案。把数字全部看作小写字母,除非在数字前加上一个下划线,这样后面一个数字可以看作大写(用于分割一个单词)。
对于 idl 需要转换为驼峰命名时,我们简单的把 idl 的名称中下划线去掉即可;需要转换为下划线分割的时候,则按大写字母或下划线加数字来分割。

比如在 idl 中写 Texture_2D
,转换为驼峰命名时为 Texture2D
,转换为下划线的宏则为 TEXTUTR_2D

Format_8x1
的驼峰命名为 Format8x1
,下划线版本为 FORMAT_8X1

Uint10
的驼峰命名为 Uint10
,下划线版本为 UINT10