大多數的教科書都說,goto標籤能不用就不用,
它會破壞程式的邏輯,並且難以追蹤行進流程,
但如果好好使用時,其實是相當安全且方便的。
甚至連大廠NI的原廠範例程式碼都是這樣寫的,
原廠大神都在用了,我們也來了解一下吧。
先前寫過一篇 [重構] - 重構Return , 多個Return整合成單一Return ,
主要將多個 return 路徑濃縮成一個,比較好掌握程式的脈絡,
而此篇要討論的方式,其實也可以應用至該篇的情境,
這樣就不必像該篇文章一樣把整段程式碼從頭跑到尾才return,
其中的利弊與情境,可以自行判斷與取捨。
回頭討論 goto 標籤的使用方式。
現在在公司的開發習慣會將function的回傳值都設為int,
主要是用來回傳 Error Code 錯誤碼,
即使運作正常也會回傳0來作為運作正常的回報。
因此我在撰寫一個新的function時,基本結構如下:
建立一個新function時,我會先把名為 result 的int變數宣告為0,
並同時在function結尾建立名為Error的標籤,
在標籤後面執行return result的動作。
因此只要在function內任何一個位置發生錯誤或非預期的情況,
就可以直接透過goto語法,跳過還沒執行的程式碼,
直接回傳result,這樣設計符合單一出入口原則,
也能更有效率的執行程式碼,因為執行尚未執行的部分,
而該部分也不需要透過flag判斷是否該繼續執行(如同此篇文章)。
而該如何呼叫goto呢?
透過 #define 定義一個function : checkErr ,參數為fCall。
fCall傳遞給result,接著result透過三元判斷式判斷是否為Sucess,
這邊Sucess定義為0,而所有的Error Code都定義為負值,
因此只要是負值,就會判定為true,
就會落入 if 判斷式的 true區塊,
進而執行 { goto Error; }。
來看看怎麼使用:
假設這個function匯集了所有硬體啟動的function,
而我們直接使用 checkErr() 去承接 Camera function 的回傳值,
假設回傳值非0 ,即代表初始化失敗,這樣就會直接啟動goto,
直達Error標籤,略過其他硬體的啟動function,
增加程式碼的執行效率。
以下為InitialCamera()的內容:
此時在這個包裝原廠API的function中,就可以回傳自定義的Error Code,
不但能統整各個廠商的 Error Code,作為開發者也比較容易進行管理。
提供一個goto的使用情境給大家參考。
沒有留言:
張貼留言