以 Go 語言的函數ReadFile
爲例。定義以下:javascript
func ReadFile(filename string) ([]byte, error)
這個函數會將error
返回。事實上,大部分 Go 語言 API 都有將error
返回的特徵。(推薦的)調用方式以下:前端
//... data, err = ReadFile("example.dat"); if (! err) { //... } //...
一些編程語言的 API,會提醒使用者「異常可能會出現」,暗示使用者「立刻去作異常處理」。然而異常處理的設計過程會中斷正常邏輯思路。若是異常處理鏈過長,迴歸到正常邏輯的時候可能一臉懵逼。java
所以,異常處理的首要原則是「正常優先」。也就是說,若是代碼寫到這裏才發現「可能須要設計異常處理」(即異常處理不在原有的設計預期之中),那就無視之(最多留個註釋),優先完成正常邏輯。編程
這裏的「異常設計」是廣義的,並不限定在try {...} catch (exception) {...}
的形式上。準確來講,「異常設計」它還包含了「容錯設計」。如下列 JavaSript 代碼爲例:服務器
// add.js export default function add (a, b) { return a + b; }
這個函數的做用是計算兩個數的和。請注意:JavaScript 不會驗證參數和返回值的類型。因此,若是這個函數是個 API,調用者可能會傳入類型不正確的參數,獲得不正確的結果。例如:網絡
// index.js import add from './add.js'; console.log(add('3' + 4)); // 34
具有「異常設計」的代碼是:編程語言
// add.js export default function add (a, b) { if (typeof(a) !== 'number' || typeof(b) !== 'number') { throw 'Error: parameters must be number.' } return a + b; }
例子中的if (condition) {...}
嚴格來講屬於「容錯設計」,本文中將其歸類爲「異常設計」(調用參數異常),也應當遵照上文說起的「正常優先」原則。函數
異常設計的第2個原則是「自用忽略」。也就是說,若是開發者設計 API 只會被本身調用,則不要設計異常處理。fetch
爲自用 API 設計異常處理有兩大弊端:設計
若是自用 API 將要被髮布,可能會被其餘開發者使用,這時就須要考慮異常處理的問題了。
異常設計的第3個原則是「量力而行」。也就是說,對因信息缺失或環境限制而沒法處理的異常,或拋出(throw)或終止(terminate)或無視(ignore)。
例如:
add
。