打开主菜单

BOO入門 > 例外 (上一章:列舉 下一章:將函數當作物件與多執行緒)


定義 定義 例外:在電腦程序裡用來處理執行時期錯誤或其他問題的方法。

例外非常重要,每當系統發生錯誤時,例外就會被提出。

捕捉例外编辑

如果沒有捕捉到例外的話,程序將會被中止。

// Division by Zero
print 1 / 0

輸出結果

System.DivideByZeroException: Attempted to divide by zero.
   at Test.Main(String[] argv)

這個例外造成程序中止。

要處理這種情形,我們得捕捉例外。我們可以使用 try-except 述句、try-ensure 述句或者是 try-except-ensure 述句。所有的例外都繼承自 Exception 類別。

// try-except 範例
import System

try:
    print 1 / 0
except e as DivideByZeroException:
    print "Whoops"
print "Doing more..."

輸出結果

Whoops
Doing more...

如你所見到,在捕捉例外之後,程序不會因為錯誤而中止,仍舊繼續執行。

捕捉錯誤並不只限於一個,你可以寫多個 except 來捕捉多種例外。

Try-ensure 用在確保某些事情能完成,不管錯誤有沒有發生。

// try-ensure 範例
import System

try:
    s = MyClass()
    s.SomethingBad()
ensure:
    print "This code will be executed, whether there is an error or not."

輸出結果

This code will be executed, whether there is an error or not.
System.Exception: Something bad happened.
   at Test.Main(String[] argv)

從上面例子你可以看到,ensure 區塊裡的程式不管錯誤有沒有發生都會被執行。

而 try-except-ensure 則結合兩者:

// try-except-ensure 範例
import System

try:
    s = MyClass()
    s.SomethingBad()
except e as Exception:
    print "Problem! ${e.Message}"
ensure:
    print "This code will be executed, whether there is an error or not."

輸出結果

Problem: Something bad happened.
This code will be executed, whether there is an error or not.
  建議 如果你不打算在 except 述句裡解決問題,你可以使用 raise (下節會介紹)不帶任何參數再把原來的例外提出,讓後續的程序去處理。

提出例外编辑

或許你會想提出自己的例外,這時候可以使用 raise 關鍵字。

// 提出例外
import System

def Execute(i as int):
    if i < 10:
        raise Exception("引數 i 必須大於或等於 10")
    print i

當傳入不適當的值給 Execute 時,例外將會被提出。

  建議 在正式上線的環境下,你應該建立自己的例外,即使這個例外只是包裹標準的 Exception 類別然後換個名字而已。
  建議 永遠別使用 ApplicationException 。

譯註:原文為 Raising Exceptions,C++ 用 throw,因此可以用擲出例外或丟出例外,用 Raise,我想用提出例外或許比較好。

練習编辑

  1. 試著去捕捉多個例外看看
  2. 試著繼承 Exception,並且提出(raise)