养成好的code style
这里主要从代码格式、标识符命名和注释三个方面,讲一下怎么“写出好的code style”。
留白的艺术
好程序里的空白行至少要占到总行数的20%以上
恰当地运用空格和空行,不为了“节省篇幅”和“紧凑”而把很多语句挤在一起,保持适当的阅读节奏。
演示示例:
- 未留白的代码
if(!value.contains("xxx")){
LOGIT(WARNING,"value is incomplete.\n")
return;
}
char suffix[16]="xxx";
int data_len = 100;
if(!value.empty()&&value.contains("tom")){
const char* name=value.c_str();
for(int i=0;i<MAX_LEN;i++){
... // do something
}
int count=0;
for(int i=0;i<strlen(name);i++){
... // do something
}
}
- 留白的代码
f (!value.contains("xxx")) { // if后{前有空格
LOGIT(WARNING, "value is incomplete.\n") // 逗号后有空格
return; // 逻辑联系紧密就不用加空行
}
// 新增空行分隔段落
char suffix[16] = "xxx"; // 等号两边有空格
int data_len = 100; // 逻辑联系紧密就不用加空行
// 新增空行分隔段落
if (!value.empty() && value.contains("tom")) { // &&两边有空格
const char* name = value.c_str(); // 等号两边有空格
// 新增空行分隔段落
for(int i = 0; i < MAX_LEN; i++){ // =;<处有空格
... // do something
}
// 新增空行分隔段落
int count = 0; // 等号两边有空格
// 新增空行分隔段落
for(int i = 0; i < strlen(name); i++){ // =;<处有空格
... // do something
}
}
命名的艺术
做好代码格式的调整后,接下来我们要操心的就是里面的内容了,而其中一个很重要的部分就是为变量、函数、类、项目等的命名。
函数的命名风格已知的有匈牙利命名法、CamelCase、snake_case,这里选择自己喜欢的方式即可。
这里演示我的命名习惯。
演示示例:
#define MAX_PATH_LEN 256 // 宏定义,全大写
int g_sys_flag; // 全局变量,加g_前缀
namespace linux_sys { // 名字空间,全小写
void get_rlimit_core(); // 函数,全小写
}
class FilePath final // 类名,首字母大写
{
public:
void set_path(const string& str); // 函数,全小写
private:
string m_path; // 成员变量,m_前缀
int m_level; // 成员变量,m_前缀
};
除此之外,变量名和函数名等尽量使用英文命名。而不是无意义的字符、汉语拼音、汉语拼音的缩写和无意义的单词缩写,当然还可以用一些已经在程序员之间形成了普遍共识的变量名,比如用于循环的i/j/k、用于计数的count、表示指针的p/ptr、表示缓冲区的buf/buffer、表示变化量的delta、表示总和的sum等。
还有一点建议是:变量/函数的名字长度与它的作用域成正比,也就是说,局部变量/函数名可以短一点,而全局变量/函数名应该长一点。(个人感觉在阅读代码时可以起到一定的作用)
用好注释
注释主要用来阐述目的、用途、工作原理、注意事项等代码本身无法“自说明”的那些东西。因此,注释必须要正确、清晰、有效,尽量言简意赅、点到为止,不要画蛇添足,更不能写出含糊、错误的注释。
演示示例:
未注释的模板函数
template<typename T>
int get_value(const T& v);
注释的模板函数
/**
* @author : zaizai is here
* @date : 2022-08-30
* @purpose : get inner counter value of generic T
* @notice : T must have xxx member
* @notice : return value maybe -1, means xxx, you should xxx
*/
template<typename T>
int get_value(const T& v);
虽然代码很简单,但未注释时可用的信息太少了,并不知道各个参数的具体要求,但可以给它加上作者、功能说明、调用注意事项、可能的返回值,等等,这样看起来就会清晰很多。当然,写法只是提供参考,具体风格可以参考doxygen、javadoc-The Java API Documentation Generator等工具。
此外,除了给代码、函数、类写注释,最好在文件的开头写上本文件的注释,里面有文件的版权声明、更新历史、功能描述,等等。
演示实例:
/**
* Copyright (c) 2022 by zaizai is here
* @file : zaizai is here
* @date : 2022-08-30
* @desc : ...
*/
另外,注释还有一个很有用的功能就是todo,作为功能的占位符,提醒将来的代码维护者,比如:
/**
* @TODO: change it to unordered_map
* @XXX: fixme later
*/
总的来说,要写好注释,你要时刻“换位思考”,设身处地去想别人怎么看你的代码,这样的话,上面的那些细则也就不难实施了。