以 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
。