[toc]

原则

选择描述性的词语,名称要能够描述它所代表的意思,要尽可能的存更多的意思。

检测

  • 将名字告诉别人,如果别人的想到的和你考虑到的一样,那么代码可读性就可以了
  • 将命名读出来,自己感受是否清晰
  • 一段时间后再读自己的代码试试

命名规范

匈牙利命名法

匈牙利命名法是在 1972 年至 1981 年期间一个程序员发明的,这种规范的主要思想就是给变量加上一个表示变量类型的前缀。不过这种方法有其复杂的历史渊源,现在几乎快被淘汰了。

wiki:

在系统匈牙利命名法中,前缀代表了变量的实际数据类型

ex:

int iMyData;      

下划线命名法

下划线命名法使用下划线分割单词,这种规范在 c 语言中使用得比较多。

ex:

int my_data;

驼峰式命名法

驼峰式命名法又叫小驼峰式命名法,这种规范要求第一个单词的首字母小写,后面其他单词首字母大写

ex:

int myData;

帕斯卡命名法

帕斯卡命名法,又叫大驼峰式命名法。

与小驼峰式命名法的最大区别在于,每个单词的第一个字母都要大写。

ex:

int MyData;

建议

选择专业的词语

对特定领域的操作,使用这个领域的专业词汇。

例如操作 Thread ,使用 Stop() 显然有让它 start 的意思,但是根据情况也有不同的可能,可能是彻底 kill,也可能是暂时 pause,所以使用后者 kill() 或 pause() 这种专业操作 thread 的更加准确。

避免使用空洞的词语

如 tmp, result 这种很常见,但是实际上并没有包含有用的信息的词语,要避免使用。

选择合适的长度

我们给代码命名的原则都是为了增加可读性,因此一般只要能准确表述其意,稍微长些是没什么问题的,何况现在的代码补全工具非常发达。具体选择怎样的长度显然是没有一个硬性规定的,但是有一些建议:

  • 作用域越大,一般命名更长

  • 如果单词有常见的缩写,那么使用这些缩写(见副表),如 msg 表示 message

  • 如果单词没有常见的缩写,那么就不要缩写。

  • 有目的的使用特定的前后缀、下划线, 如给 password 加上 plainText_表示其未加密的状态

避免使用具有二义性的词语

  • min_max_ 前缀表示极限
  • first_last_ 前缀表示包含的范围
  • beginend 表示包含/排除的范围

避免使用相似的字符

如 I 和 1, 0 和 o, 0 和 O, S 和5 , G 和 6

避免变量名使用数字

这一点并不是一定的,但是像那种表示数目的添加数字,如 str1, str2, str3,请避免这样写,如果它们之间的确有关系,请使用数组来区分,如果没有关系,更不要使用这种难以取分的名词,最好使用能描述它们本来意义的词语。

特殊类型

布尔值

原则:使用非真即假的名字给布尔值命名。

status,就不只非真即假,那么使用这个作为名字是不合理的,我们可以给它加后缀,变成 statusOk, 就显然只有两种值了。

  • 加前缀

    • 如果表示是不是,加前缀 is

    • 如果表示有没有,加前缀 has

    • 如果表示能不累,加前缀 can

  • 加后缀

    • 如果词语不是形容词,则变为形容词,如加 able
    • 如果表示已经完成,则加 Done 或 complete 或 Sucess 或 Ok
    • 如果表示找到某个值,则加 Found
    • 如果表示发生了错误,则加 Error

循环变量

通常使用 i, j, k 等字母作为循环变量,如果迭代的次数比较少,比如一、两次,那么使用这些是没有问题的,因为这是约定俗成的,大家都知道它们代表什么。但是迭代的次数多起来之后,或则我们在循环外也需要使用这些变量,那么我们就很难直接看出它代表什么。

  • 对于迭代次数较多,如下:
for (i = 0; i < clubs.size(); i++)
    for (j = 0; j < clubs.members.size(); j++)
        for (k = 0; k < users.size(); k++)
            if (club[i].members[k] == users[j])            

在 if 语句中, 显然 members 和 users 用错了索引,但是这种逻辑错误并不是语法错误, Ide 很难检查出来。

对于像这种多层迭代的索引,建议把每个索引的位置加在命名中。如 clubsIndex, membersIndex, usersIndex, 或

clubsI, membersI, usersI, 或更加简洁 ci, mi, ui。 当然,你也可以把 i 变为前缀表示索引,如 ic, im, iu。这样做大大的增加了索引的可读性。

  • 对于迭代外需要使用的,如:
for i, k := range "Hello" {
    //
}

对于这种情况,最好按照普通的变量那样命名,即将使用描述性的语句表达出变量的意义。如此处,i 表示 index, k 表示 value, 我们可以直接命名为 strIndex, strValue

常量

不同编程语言,不同的项目团队都有着不同的规范。对于常量的命名不同人也有不同规范。有人全用大写字母,也有人用驼峰式,google 的 c++ 约定常量加一个前缀 k。这个只要有规范并遵守就好,并不强求。

我个人一般加 _C 后缀表示常量。

暂时变量

暂时使用单首字母。如:

var u User;

全局变量

加上 g_ 前缀

枚举

加上 _e 后缀

文件命名

一般文件/文件夹的命名遵循以下规则:

  • 全小写
  • 使用下划线分割单词

特殊:

Makefile, README.md 等

ex:

my_test_file.go

Q&A

  • 代码是越少越好吗?

代码过又臃肿的话显然效率不会太高,但是反之代码就越少越好吗?让我们看这段代码

  • 我该使用什么命名规范?

实际不同于书本,并不存在某种方法能应对所有的情况。实际项目中一般是取多种规范的优点,再根据实际情况使用。推荐 public 变量和 public 方法使用帕斯卡命名法,private 变量和方法使用小驼峰式命名法。这种命名是现在项目比较常用的。

相关文章

参考书籍

  • 《编写可读代码的艺术》
  • 《代码大全》
  • 《代码整洁之道》

检查表

  • 名字完整并且准确的表达了变量所代表的含义吗?
  • 名字足够长,可以让你无需苦苦思索吗?
  • 如果有计算限定符,它被放在名字后面吗?
  • 名字中用 Count 或者 index 来掉提 Num 了吗?
  • 循环变量的名字有意义吗?
  • 所有临时的变量都重新命名为更有意义的名字了吗?
  • 当布尔变量为真时,变量能准确表达其含义吗?
  • 枚举中的名字含有能够表示其类别的前缀或者后缀吗?
  • 命名常量是否代表的是实体而非其代表的数值?
  • 命名规则能够区分局部数据,类的数据和全局数据吗?
  • 名字能够读出来吗?
  • 名字没有无法辨别的字符吗?

常见缩写表

缩 写 全 称
addr address
adm Administrator
app application
adm administrator
arg Argument
asm assemble
asyn asynchronization
avg average
bk back
bmp bitmap
btn button
buf buffer
calu calculate
chg change
clk click
clr color
cmd command
cmp compare
col column
coord coordinates
cpy copy
ctl/ctrl control
cur current
cyl cylinder
char character
dbg debug
db database
dbl double
dec decrease
def default
del delete
dest/des destination
dev device
dict dictionary
diff different
dir directory
disp display
div divide
dlg dialog
doc document
drv driver
dyna dynamic
dlg dialog
env error
ex/ext extend
exec execute
flg flag
frm frame
func/fn function
grp group
horz horizontal
idx/ndx index
img image
impl implement
inc increase
info information
init initial/initialize/initialization
ins insert
inst instance
intr/INT interrupt
len length
lib library
lnk link
log logical
lst list
max maximum
mem memory
mgr/man manage/manager
mid middle
min minimum
msg message
mul multiply
num number
obj object
ofs offset
org origin/original
param parameter
pic picture
pkg package
pnt/pt point
pos position
pre/prev previous
prg program
prn print
proc process/procedure
prop properties
psw password
ptr pointer
pub public
rc rect
ref reference
reg register
req request
res resource
ret return
rgn region
scr screen
sec second
seg segment
sel select
src source
std stqandard
stg storage
stm stream
str string
sub subtract
sum summation
svr server
sync synchronization
sys system
tbl table
temp/tmp temporary
tran/trans translate/transation/transparent
tst test
txt text
unk unknown
upd update
upg upgrade
util utility
var variable
ver version
vert vertical
vir virus
win window