代碼審查又被懟了?學(xué)會(huì)這三個(gè) C++17 屬性立刻提升代碼質(zhì)量
小王最近剛?cè)肼氁患一ヂ?lián)網(wǎng)公司,今天又是元?dú)鉂M滿的一天 ??
"老張,救命??!" 小王沖進(jìn)辦公室,手里還拿著自己的保溫杯。
老張正在喝著他標(biāo)志性的枸杞泡茶 ??,抬頭看了看慌張的小王:"怎么了?又遇到什么難題了?"
"我們的代碼審查工具一直報(bào)警,說什么 switch 語(yǔ)句有 fall through 問題。我看了半天文檔也沒看明白..." 小王撓著頭發(fā),一臉困惑 ??
老張放下保溫杯,露出了高深莫測(cè)的微笑:"哦?這個(gè)問題啊,來(lái)來(lái)來(lái),我給你講個(gè)故事..."
從一個(gè) bug 說起
"先看這段代碼:"
switch (value) {
case 1:
doSomething();
// 警告:這里有個(gè)隱藏的陷阱!
case 2:
doSomethingElse();
break;
}
"誒?這代碼有什么問題嗎?" 小王湊近屏幕 ??
"你還記得上周那個(gè)用戶投訴的 bug 嗎?" 老張喝了口枸杞茶。
小王一拍腦門:"對(duì)對(duì)對(duì)!就是那個(gè)訂單狀態(tài)莫名其妙變化的問題!"
"沒錯(cuò),就是這種 switch 語(yǔ)句惹的禍。" 老張放下茶杯,"你看,如果 value 是 1,程序不僅會(huì)執(zhí)行 case 1 的代碼,還會(huì)繼續(xù)往下執(zhí)行 case 2 的代碼..."
"啊!" 小王恍然大悟,"原來(lái)是忘記寫 break 了!" ??
C++17 的救星
老張點(diǎn)點(diǎn)頭:"但有時(shí)候,我們確實(shí)需要這種特性。C++17 給我們提供了一個(gè)優(yōu)雅的解決方案:"
switch (value) {
case 1:
doSomething();
[[fallthrough]]; // 告訴編譯器:這是故意的!
case 2:
doSomethingElse();
break;
}
"這...這簡(jiǎn)直太棒了!" 小王興奮地說,"等等,我記得還看到過其他類似的標(biāo)記..." ??
別讓返回值白白浪費(fèi):[[nodiscard]] 屬性
"說到這個(gè)..." 老張神秘地笑了笑,從抽屜里掏出一個(gè)小本本 ??,"你知道為什么我總能快速定位問題嗎?"
小王搖搖頭,一臉好奇 ??
"因?yàn)槲野巡冗^的坑都記在這里了!來(lái)看看這個(gè)例子:"
int calculateDiscount() {
// 計(jì)算折扣金額
return discount;
}
void processOrder() {
calculateDiscount(); // 警告:返回值被忽略了!
applyTax();
}
"這段代碼有什么問題?" 老張問道。
小王仔細(xì)看了看:"嗯...計(jì)算了折扣但是沒用上?"
"沒錯(cuò)!" 老張贊許地點(diǎn)點(diǎn)頭,"這種bug特別隱蔽。有時(shí)候我們寫完代碼就忘記用返回值了。C++17 給了我們一個(gè)法寶:"
[[nodiscard]] int calculateDiscount() {
return discount;
}
"哇!這樣如果忘記使用返回值,編譯器就會(huì)報(bào)警告?" 小王眼睛一亮 ?
"聰明!" 老張喝了口枸杞茶,"不過還有個(gè)有趣的情況..."
暫時(shí)不用也不報(bào)警:[[maybe_unused]] 屬性
正說著,產(chǎn)品經(jīng)理小李急匆匆地跑了進(jìn)來(lái) ??♂?
"老張!那個(gè)新功能暫時(shí)不上了,代碼先留著!"
"說曹操,曹操就到。" 老張笑著對(duì)小王說,"這種情況我們就需要第三個(gè)屬性了:"
[[maybe_unused]] void newFeature() {
// 暫時(shí)用不上的新功能
}
void legacyFunction([[maybe_unused]] int oldParam) {
// 參數(shù)暫時(shí)不用,但后面可能會(huì)用
}
"這樣編譯器就不會(huì)對(duì)未使用的函數(shù)和參數(shù)發(fā)出警告了!" 小王恍然大悟 ??
"沒錯(cuò)!" 老張滿意地說,"這三個(gè)屬性看似簡(jiǎn)單,但都是實(shí)戰(zhàn)中的法寶?。?
"[[fallthrough]] 防止 switch 穿透事故..." "[[nodiscard]] 提醒我們別忘了返回值..." "[[maybe_unused]] 處理暫時(shí)用不上的代碼..."
小王掰著手指數(shù)著,臉上露出了開心的笑容 ??
"學(xué)會(huì)了這三個(gè)屬性,以后代碼審查就不用擔(dān)心了!" 老張拍拍小王的肩膀。
"謝謝老張!" 小王站起身來(lái),"我這就去優(yōu)化代碼!"
看著小王歡快離去的背影,老張又給自己的枸杞茶續(xù)上了熱水 ??
小結(jié)
C++17 新增的三個(gè)屬性各有妙用:
- [[fallthrough]] 用于表示 switch 語(yǔ)句中刻意的 case 穿透
- [[nodiscard]] 提醒調(diào)用者不要忽略函數(shù)返回值
- [[maybe_unused]] 標(biāo)記暫時(shí)不用但后面可能會(huì)用到的代碼
這些小工具不僅能幫助我們寫出更清晰的代碼,還能預(yù)防一些常見的bug。正如老張所說,編程就像泡茶,看似簡(jiǎn)單,但其中大有學(xué)問啊!