一、defer
defer确保在函数调用的时候执行(总是被执行),遵循先进后出的原则,参数在defer语句是计算1
2
3
4
5
6
7func main() {
defer fmt.Println(1)
defer fmt.Println(2)
fmt.Println(3)
return
fmt.Println(4)
}
输出的顺序为 3 2 1
示例:创建一个文件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16func writeFile(fileName string){
file, e := os.Create(fileName)
if nil != e {
log.Println("异常:",e.Error())
return
}
//关闭io
defer file.Close()
//使用缓冲提高效率
writer := bufio.NewWriter(file)
// 保证释放 写入
defer writer.Flush()
fmt.Fprintln(writer,"Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。")
}
二、panic
panic是用来表示非常严重的不可恢复的错误的,向外抛出异常,程序不在往下执行,逐层向上返回,并执行每一层上面的defer;如果没有recover,程序结束运行
panic(“异常信息”)
1 | func main() { |
输出的顺序为 3 2 1
三、recover
recover仅在defer条用中执行,可以获取到panic的信息,如无法处理,还可以重新panic1
2
3
4
5
6
7
8
9
10
11
12
13
14
15func tryRecover() {
//使用 defer 保证该匿名方法总被执行
defer func() {
r := recover()
if err,ok := r.(error); ok{
fmt.Println("recover 异常信息是 ",err)
}else{
panic("不是error类型的错误.")
}
}()
//制造一个异常
//panic("这是一个错误信息...") //不是error类型
panic(errors.New("这是一个错误信息..."))
}
四、自定义error
需要实现builtin包的接口type error interface {Error() string}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
39type User struct {
name,pwd string
}
type LoginError struct {
msg string
}
//自定义异常
func (err *LoginError) Error() string {
return err.msg
}
func login(name string,pwd string) (*User,error) {
if name != "go" {
return nil, &LoginError{msg:"登录账号异常..."}
}
if pwd != "123456" {
return nil, &LoginError{msg:"密码错误..."}
}
return &User{name:name,pwd:pwd}, nil
}
func main() {
user, e := login("go", "123456")
if nil != e {
loginError,ok:= e.(*LoginError)
if !ok {
//未知的异常类型 不处理 抛出
panic(e)
}else{
fmt.Println(loginError.Error())
}
}else{
fmt.Println(user)
}
}