常见优秀代码汇总_帅气滴点c的博客-爱代码爱编程
汇总常见的编程习惯
1. 语义简单明确
含义:写代码时考虑读者,优先采取易于读者理解的写法。
#define THROTL_UNSET -2
#define THROTL_NO_LIMIT -1
bool throttle_is_quota_valid(int64_t value)
{
// 复杂的判断条件
// 请你在三秒内说出 value 如何取值是合法的?
if (value < 0 && value != THROTL_UNSET && value != THROTL_NO_LIMIT)
{
return false;
}
return true;
}
bool throttle_is_quota_valid(int64_t value)
{
// 这是修改后的代码,value 取值合法有三种情况,一目了然
return value >= 0 || value == THROTL_UNSET || value == THROTL_NO_LIMIT;
}
2. 简洁 ≠ 代码短
简洁≠代码短,复杂的问号表达式反而不如 if..else 方便理解。
void RecycleBin::Load(BindCallbackR1<Status>* done)
{
......
FOREACH(iter, fileStats)
{
RecycleFile item;
Status status = ParseDeletedFileName(iter->path, &item.timestamp);
if (!status.IsOk() { ...... }
item.fileName = iter->path;
item.size = iter->size;
item.physicalSize = iter->refCount > 1 ? 0 : iter->physicalSize;
......
// 这是修改前的代码
earliestTimestamp[item.medium] =
item.timestamp != 0 && item.timestamp < earliestTimestamp[item.medium] ?
item.timestamp : earliestTimestamp[item.medium];
}
// 这是修改后的代码
if (item.timestamp != 0 &&
item.timestamp < earliestTimestamp[item.medium])
{
earliestTimestamp[item.medium] = item.timestamp;
}
}
......
}
3. 提前返错
提前返错能减少主体逻辑的缩进数量,让主体代码逻辑显得更醒目。
Status Foo()
{
Status status = Check1();
if (!status.IsOk())
{
return status;
}
else
{
status = Check2();
if (!status.IsOk())
{
return status;
}
else
{
..............
}
}
}
//修改为
Status Foo()
{
Status status = Check1();
if (!status.IsOk())
{
return status;
}
status = Check2();
if (!status.IsOk())
{
return status;
}
}
4.利用析构函数做清理工作(针对C++)
利用 C++ 析构函数做清理工作,在复杂冗长代码中不会漏掉。典型的清理工作有执行回调、关闭文件、释放内存等。
void Foo(RpcController* ctrl,
const FooRequest* request,
FooResponse* response,
Closure* done)
{
Status status = Check1(request);
if (!status.IsOk())
{
response->set_errorcode(status.Code());
// 第一处
done->Run();
return;
}
status = Check2(request);
if (!status.IsOk())
{
response->set_errorcode(status.Code());
// 第二处
done->Run();
return;
}
DoSomeRealWork(...);
// 第三处
done->Run();
}
//修改为:
void Foo(RpcController* ctrl,
const FooRequest* request,
FooResponse* response,
Closure* _done)
{
// 仅一处,不遗漏
erpc::ScopedCallback done(_done);
Status status = Check1(request);
if (!status.IsOk())
{
response->set_errorcode(status.Code());
return;
}
status = Check2(request);
if (!status.IsOk())
{
response->set_errorcode(status.Code());
return;
}
DoSomeRealWork(...);
}
5. 用朴素直观的算法
在非关键路径上,优先使用朴素直观的算法,此时代码可维护性更重要。
void CompactTask::checkFileUtilizationRewrite()
{
// 此处采取朴素的排序算法,并未采取更高效的 TopK 算法
std::sort(sealedFilesUsage.begin(), sealedFilesUsage.end(), GarbageCollectionCompare);
int64_t sealedFileMaxSize = INT64_FLAG(lsm_CompactionSealedMaxSize);
int32_t sealedFileMaxNum = INT32_FLAG(lsm_CompactionSealedMaxFileNum);
int64_t targetFileSize = 0;
int32_t sourceFileCnt = 0;
// 前者简单清淅,并在几十个 File 中选择前几个文件的场景并不算太慢
FOREACH(itr, sealedFilesUsage)
{
LogicalFileId fileId = itr->fileId;
const FileUsage* usage = baseMap->GetFileUsage(fileId);
const File* file = fileSet->GetFile(fileId);
targetFileSize += usage->blocks * mBlockSize;
sourceFileCnt++;
if (targetFileSize > sealedFileMaxSize || sourceFileCnt > sealedFileMaxNum)
{
break;
}
mRewriteSealedFiles[fileId] = true;
}
......
}
6.用轮循代替条件变量
在非关键路径上使用简单的轮循代替精巧的条件变量同步,代码简洁且不容易出 bug。
7. 避免有歧义的函数名和参数表
函数名和参数表要符合直觉,大多数使用者没空读你的注释,小部分使用者读了你的注释也看不明白。
参考文献: