3

在我看到異常(C++,Java,Javascript,Python,PHP等)的語言中,我總是看到try或類似的東西來標記catch的範圍。我想知道是否有必要。 try塊有什麼設計問題?語言設計(例外):爲什麼`嘗試`?

例如,藉此:

try{ 
    try{ 
     do_something_dangerous0(); 
    }catch (SomeProblem p){ 
     handle(p); 
    } 
    try{ 
     do_something_dangerous1(); 
    }catch (SomeProblem p){ 
     handle(p); 
    } 
}catch (SomeOtherProblem p){ 
    handle(p); 
} 

我想象這作爲替代。

do_something_dangerous0(); 

catch (SomeProblem p){ 
    handle(p); 
} 

do_something_dangerous1(); 

catch (SomeProblem p){ 
    //catches from only the second unless the first also threw 
    handle(p); 
} 

catch (SomeOtherProblem p){ 
    //catches from either, because no other block up there would 
    handle(p); 
} 

如果你想避免塊醒目「太多」,你可以做一個新的範圍:

do_something_dangerous2(); 

{ 
    do_something_dangerous3(); 

    catch (SomeProblem p){ 
     //does not catch from do_something_dangerous2() 
     //because if that throws, it won't reach in here 
     handle(p); 
    } 
} 

catch (SomeProblem p){ 
    handle(p); 
} 

catch (SomeOtherProblem p){ 
    handle(p); 
} 

(我爲什麼這不會對語言,如C工作答案++和Java ,至少在下面發佈爲答案,但我沒有針對動態語言的答案。)

+0

在一般情況下,您需要精確定界異常處理範圍的開始和結束。人們可以爲此使用「孤獨」的範圍,但它不會真正改變任何事情,並且不太清楚。 –

+0

(我曾經在一個使用BEGIN/NIGEB宏定義異常處理範圍的系統上工作,但總體結構幾乎與try/catch/finally完全相同,該函數決定語法,而不是其他方法。) –

+0

我是不是用'如果你想避免一個障礙物'太多'......'呢? – leewz

回答

4

對於至少需要變量聲明的語言來說,它不起作用。

try塊中的任何語句都可能無法完全執行,包括變量的聲明和初始化。在具有塊範圍界定的語言中,尤其是需要變量聲明(如C++,Objective C和Java)的語言時,catch塊不共享try塊的範圍,因此不允許訪問try的局部變量。 try -less系統會破壞範圍規則。

例如,這是有效的C++代碼。

try{ 
    int x = some_func(); 
    int y = some_other_func(); 
}catch(SomeException){ 
    //... 
} 

如果換算成,

int x = some_func(); 
int y = some_other_func(); 

catch(SomeException){ 
    //... 
} 

然後,下支架範圍規則,xy是在範圍內的catch塊,即使他們可能不聲明/尚未初始化。

您可以更改作用域規則,使catch不會看到這些變量聲明,但是這是一個非常簡單和普遍規則的主要併發症,以節省大約七個字符(try{\n}\n)。你可以這樣做,以便你不能立即在catch的範圍外進行變量聲明,但是如果沒有像try這樣的塊,那麼你就不能做很多事情。你可以在運行任何可以拋出的東西(類似於舊C)之前聲明一個範圍中的所有變量,但是這會在構造代碼時帶來一些自由,並且使其更難以閱讀。