![](/img/trans.png)
[英]In an If-Else Statement for a method return, should an Else be explicitly stated if it can instead be implicitly followed?
[英]Should I use return/continue statement instead of if-else?
在C,C ++和C#中,當在函數或循環語句中使用條件時,可以盡早使用continue語句或return語句,並刪除if-else語句的else分支。 例如:
while( loopCondition ) {
if( innerCondition ) {
//do some stuff
} else {
//do other stuff
}
}
變
while( loopCondition ) {
if( innerCondition ) {
//do some stuff
continue;
}
//do other stuff
}
和
void function() {
if( condition ) {
//do some stuff
} else {
//do other stuff
}
}
變
void function() {
if( condition ) {
//do some stuff
return;
}
//do other stuff
}
如果if-else分支很長,則“after”變體可能更具可讀性,因為此更改消除了else分支的縮進。
是這樣使用返回/繼續一個好主意? 是否有任何可能的維護或可讀性問題?
我個人選擇的方法是,如果if
部分的主體非常短(最多3或4行),則使用return/continue
變體是有意義的。 如果身體很長,那么跟蹤控制流程就更難了,所以我選擇了else
版本。
因此,通常,此方法限制return/continue
樣式的使用以跳過某些數據並避免進一步處理,而不是使用以下方法之一處理此方法 ( if/else
更適合)。
編譯器幾乎肯定會生成相同的代碼。 即使它沒有,差異可能是無關緊要的。 因此,相關論點肯定是人們如何閱讀它。
因此,問題是“//做一些東西”和“做其他東西”是多么相似。 如果它們在概念上相似,請使用if / else。 如果它們在概念上不同,請使用continue / return。
這取決於分支的長度。 如果初始if
檢查很短,並且正文很長,那么使用你描述的return / continue是好的。 如果if
和else
部分都很長,我會將它們提取到單獨的函數中。
我建議閱讀Code Complete,它會討論很多這樣的事情。
如果首先處理終止條件,則代碼將更易讀。 我總是喜歡,檢查需要中斷或返回的條件而不是那些需要冗長代碼執行的條件。 我更喜歡:
if (termination condn)
return;
// code
// code
至
if (success condn)
{
// code
// code
}
else
return;
這使得閱讀和理解代碼更容易。
巧妙的回答是,這一切都取決於。
我的一般感覺是,如果condition
是罕見的,保護(例如檢查為空)或錯誤條件,那么我傾向於使用return
或continue
如果這是一個預期的案例,那么我傾向於使用你的第一種方法。
但請注意,我說“傾向”。 這些條件之間的界限是模糊的,可能會根據項目和我正在與誰合作而變化。
我通常更喜歡
while( loopCondition ) {
if( innerCondition ) {
DoStuff();
} else {
DoOtherStuff();
}
}
如果DoStuff的長度超過1-2行閾值(並且很容易錯過意圖),則很難繼續。 這似乎是將邏輯重構為一些較小方法的好機會。
不要為了過早優化而犧牲可讀性。
例如:
void function() {
if( condition ) {
//do some stuff
} else {
//do other stuff
}
}
在大多數情況下二進制等價於
void function() {
if( condition ) {
//do some stuff
return;
}
//do other stuff
}
(即結果代碼可能相同)。 但是前者的可讀性要好得多,因為你可以清楚地看到代碼將是X或Y.
1) 輸入或對象狀態驗證 。 以下代碼:
void function() {
if( condition ) {
//do some stuff
return;
}
//do other stuff
}
當條件是功能工作的一些要求時,這是好的。 這是輸入驗證或對象狀態驗證的一個階段。 然后,立即使用返回來強調它是正確的,該功能根本沒有運行。
2) 多級處理 。 當循環從某個集合中彈出元素並以多級方式處理它們時,/ continue很好:
while(foo = bar.getNext()) {
if(foo.empty())
continue;
if(foo.alreadyProcessed())
continue;
// Can we take a shortcut?
if(foo.tryProcessThingsYourself())
continue;
int baz = foo.getBaz();
if(baz < 0) {
int qux = foo.getQux();
if(qux < 0) {
// Error - go to next element
continue;
}
}
// Finally -- do the actual processing
baz = baz * 2;
foo.setBaz(baz);
}
該示例顯示了在完成一系列多級處理時,在每個處理可能被各個地方的各種條件中斷時,使用“ 繼續 ”的自然程度。
注意: plinth發布了真實的例子,它遵循2)所說的。
3) 一般規則 。 我使用continue並返回,因為它與某些事物被中斷的事實相對應。 當else是實際處理的一部分時,我使用else 。
一個可能的維護問題是,如果一個函數有多個返回,那么在調試時很難在返回時粘貼斷點或跟蹤。 這很少是一個問題,但當你錯過一個回歸點時,這是一個痛苦。 我認為繼續循環並不重要,因為循環條件和循環頂部都是唯一的。
除此之外:其他人都在說什么。 做什么是最可讀的,這取決於“某些東西”和“其他東西”的相對長度,重要性和可能性。 更短,更瑣碎,更不可能的情況是,它具有特殊情況控制流程的不那么令人不安。
正如其他人所說,如果事情很短,只能使用返回/繼續。
我個人只使用continue,如果可以在一行寫,如:
while( loopCondition ) {
if( innerCondition ) continue;
//do other stuff
}
如果在沒有代碼變得丑陋的情況下不可能這樣寫,那么if / else。
為了笑容,我在我公司的代碼庫中搜索了“繼續”; 只是為了了解它的使用位置。 我們在一個解決方案中使用59個項目的695次,大約1500個源文件。
我看到它們被使用的主要方式是作為快速過濾器:
foreach (Frobozz bar in foo) {
if (QuickFilterExclude(bar))
continue;
// extensive processing
}
從預期的異常中恢復:
foreach (Frobozz bar in foo) {
Baz result = new Baz(kDefaultConfiguration);
try {
Baz remoteResult = boo.GetConfiguration();
}
catch (RemoteConnectionException) {
continue;
}
result.Merge(remoteResult);
ReportResult(result);
}
最后是國家機器。
跳出方法或循環時,我通常使用if-return方法,因為沒有什么可做的。
如果身體因為大量的工作而更長,我建議使用if-else並且可能使用#region為塊提供合理的名稱並讓它們容易折疊以供人們研究控制流程。 那個或制作單獨的方法:)
我的代碼中有以下內容:
while(){
boolean intersect = doesIntersect(interval_1,interval_2);
if(!intersect){
array.add(interval_2);
if(// another condition){
// Do some thing here
}
continue;
}
// other stuff to do if intersect
}
令人困惑的是我是否應該繼續使用或使用其他但我決定內部if條件可能使其他人不能很好閱讀,所以我用繼續。
我認為可讀性才是最重要的!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.