mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-08-14 18:41:42 +00:00
回到简体
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
## 7.11. 基於類型斷言區别錯誤類型
|
||||
## 7.11. 基于类型断言区别错误类型
|
||||
|
||||
思考在os包中文件操作返迴的錯誤集合。I/O可以因爲任何數量的原因失敗,但是有三種經常的錯誤必須進行不同的處理:文件已經存在(對於創建操作),找不到文件(對於讀取操作),和權限拒絶。os包中提供了這三個幫助函數來對給定的錯誤值表示的失敗進行分類:
|
||||
思考在os包中文件操作返回的错误集合。I/O可以因为任何数量的原因失败,但是有三种经常的错误必须进行不同的处理:文件已经存在(对于创建操作),找不到文件(对于读取操作),和权限拒绝。os包中提供了这三个帮助函数来对给定的错误值表示的失败进行分类:
|
||||
|
||||
```go
|
||||
package os
|
||||
@@ -10,7 +10,7 @@ func IsNotExist(err error) bool
|
||||
func IsPermission(err error) bool
|
||||
```
|
||||
|
||||
對這些判斷的一個缺乏經驗的實現可能會去檢査錯誤消息是否包含了特定的子字符串,
|
||||
对这些判断的一个缺乏经验的实现可能会去检查错误消息是否包含了特定的子字符串,
|
||||
|
||||
```go
|
||||
func IsNotExist(err error) bool {
|
||||
@@ -19,9 +19,9 @@ func IsNotExist(err error) bool {
|
||||
}
|
||||
```
|
||||
|
||||
但是處理I/O錯誤的邏輯可能一個和另一個平台非常的不同,所以這種方案併不健壯併且對相同的失敗可能會報出各種不同的錯誤消息。在測試的過程中,通過檢査錯誤消息的子字符串來保證特定的函數以期望的方式失敗是非常有用的,但對於線上的代碼是不夠的。
|
||||
但是处理I/O错误的逻辑可能一个和另一个平台非常的不同,所以这种方案并不健壮并且对相同的失败可能会报出各种不同的错误消息。在测试的过程中,通过检查错误消息的子字符串来保证特定的函数以期望的方式失败是非常有用的,但对于线上的代码是不够的。
|
||||
|
||||
一個更可靠的方式是使用一個專門的類型來描述結構化的錯誤。os包中定義了一個PathError類型來描述在文件路徑操作中涉及到的失敗,像Open或者Delete操作,併且定義了一個叫LinkError的變體來描述涉及到兩個文件路徑的操作,像Symlink和Rename。這下面是os.PathError:
|
||||
一个更可靠的方式是使用一个专门的类型来描述结构化的错误。os包中定义了一个PathError类型来描述在文件路径操作中涉及到的失败,像Open或者Delete操作,并且定义了一个叫LinkError的变体来描述涉及到两个文件路径的操作,像Symlink和Rename。这下面是os.PathError:
|
||||
|
||||
```go
|
||||
package os
|
||||
@@ -38,7 +38,7 @@ func (e *PathError) Error() string {
|
||||
}
|
||||
```
|
||||
|
||||
大多數調用方都不知道PathError併且通過調用錯誤本身的Error方法來統一處理所有的錯誤。盡管PathError的Error方法簡單地把這些字段連接起來生成錯誤消息,PathError的結構保護了內部的錯誤組件。調用方需要使用類型斷言來檢測錯誤的具體類型以便將一種失敗和另一種區分開;具體的類型比字符串可以提供更多的細節。
|
||||
大多数调用方都不知道PathError并且通过调用错误本身的Error方法来统一处理所有的错误。尽管PathError的Error方法简单地把这些字段连接起来生成错误消息,PathError的结构保护了内部的错误组件。调用方需要使用类型断言来检测错误的具体类型以便将一种失败和另一种区分开;具体的类型比字符串可以提供更多的细节。
|
||||
|
||||
```go
|
||||
_, err := os.Open("/no/such/file")
|
||||
@@ -48,7 +48,7 @@ fmt.Printf("%#v\n", err)
|
||||
// &os.PathError{Op:"open", Path:"/no/such/file", Err:0x2}
|
||||
```
|
||||
|
||||
這就是三個幫助函數是怎麽工作的。例如下面展示的IsNotExist,它會報出是否一個錯誤和syscall.ENOENT(§7.8)或者和有名的錯誤os.ErrNotExist相等(可以在§5.4.2中找到io.EOF);或者是一個*PathError,它內部的錯誤是syscall.ENOENT和os.ErrNotExist其中之一。
|
||||
这就是三个帮助函数是怎么工作的。例如下面展示的IsNotExist,它会报出是否一个错误和syscall.ENOENT(§7.8)或者和有名的错误os.ErrNotExist相等(可以在§5.4.2中找到io.EOF);或者是一个*PathError,它内部的错误是syscall.ENOENT和os.ErrNotExist其中之一。
|
||||
|
||||
```go
|
||||
import (
|
||||
@@ -69,11 +69,11 @@ func IsNotExist(err error) bool {
|
||||
}
|
||||
```
|
||||
|
||||
下面這里是它的實際使用:
|
||||
下面这里是它的实际使用:
|
||||
|
||||
```go
|
||||
_, err := os.Open("/no/such/file")
|
||||
fmt.Println(os.IsNotExist(err)) // "true"
|
||||
```
|
||||
|
||||
如果錯誤消息結合成一個更大的字符串,當然PathError的結構就不再爲人所知,例如通過一個對fmt.Errorf函數的調用。區别錯誤通常必須在失敗操作後,錯誤傳迴調用者前進行。
|
||||
如果错误消息结合成一个更大的字符串,当然PathError的结构就不再为人所知,例如通过一个对fmt.Errorf函数的调用。区别错误通常必须在失败操作后,错误传回调用者前进行。
|
||||
|
Reference in New Issue
Block a user