Hike News
Hike News

Go初識-day24-錯誤處理

定義錯誤

  • errors.New("錯誤碼") : 生成一個錯誤類型的實例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package main

    import (
    "errors"
    "fmt"
    )

    //定義一個errNotFound的變量為error類型,並用errors.New產生實例
    var errNotFound error = errors.New("NotFoundError")

    func main(){
    fmt.Printf("error : %v",errNotFound)
    }
  • 在函數外定義錯誤,在函數內引用

tips

  • error類型並不是結構體(struct)類別,而是interface
    https://golang.org/pkg/builtin/#error

  • 只要實現error接口,我們也可自定義錯誤類型

    1
    2
    3
    type error interface{
    Error() string
    }
  • 絕大多數情況下使用 errors.New() 就能滿足自定義錯的需求

自定義錯誤類型(struct)

  • 欲自定義錯誤類型並返回更多細節,可自定義錯誤類型的struct
  • 只要結構體實現了Error()這個方法就能實現error這個接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package main

import (
"fmt"
"os"
"time"
)

//定義一個結構體紀錄錯誤細節的信息
type FileNotFoundError struct {
FileName string
Path string
Time string
operation string
message string
}

//FileNotFoundError這個結構體實現了Error()方法並返回string類型
func (self *FileNotFoundError)Error()string{
return fmt.Sprintf("FileNotFound:\n %s/%s\n Time:%s\n operation:%s\n Message:%s\n",
self.Path,
self.FileName,
self.Time,
self.operation,
self.message)
}

//請注意期返回值error為接口 而不是結構體
func ReadDoc (filename string) error {
File,err := os.Open(filename)
if err != nil {
return &FileNotFoundError{
FileName : filename,
Path : "somewhere",
Time : fmt.Sprintf("%v",time.Now()),
operation : "Read",
message : err.Error(),
}
}
defer File.Close()
return nil
}

func main(){
fmt.Println(ReadDoc("fasdfsdf.txt"))
}

result

1
2
3
4
5
FileNotFound:
somewhere/fasdfsdf.txt
Time:2018-05-08 01:51:52.93837283 +0800 CST m=+0.000345825
operation:Read
Message:open fasdfsdf.txt: no such file or directory

判斷錯誤屬於何種類型

  • 判斷錯誤是否為自定義的錯誤類型
  • 可使用類型斷言來判斷,因為error類型為interface

example 1

1
2
3
4
5
6
7
func main(){
err := ReadDoc("adfsdfsfd.txt")
_, ok := err.(*FileNotFoundError)
if ok {
fmt.Println("It's FileNotFoundError Type")
}
}

result

1
It's FileNotFoundError Type

example 2

1
2
3
4
5
6
7
8
9
10
func main(){

// 使用switch搭配.type使用類型斷言判斷
switch ReadDoc("fasdfsdf.txt").(type) {
case *FileNotFoundError:
fmt.Println(v, "is type FileNotFoundError type")
default:
fmt.Println("Default")
}
}

result

1
is type FileNotFoundError type

tips

  • 實際業務開發中使用errors.New()方法還是比較多

panic & recover

  • 請參考內置函數章節有詳盡的panic與recover的介紹