基础六

  • 说明
  • 异常
    • 错误接口
    • 捕捉异常
    • 中止程序
    • 从异常中恢复

说明

  • 本章主要说明Go语言中异常处理

  • 下面的示例代码来自于这里

异常

错误接口

  • Go 程序使用 error 类型来表示错误状态,与 fmt.Stringer 类似,error 类型是一个内建接口
type error interface {
    Error() string
}
  • 通常方法会返回一个 error 值,调用的它的代码应当判断这个错误是否等于 nil, 来进行错误处理
package main

import (
    "fmt"
    "time"
)

type MyError struct {
    When time.Time
    What string
}

func (e *MyError) Error() string {
    return fmt.Sprintf("at %v, %s",
        e.When, e.What)
}

func run() error {
    return &MyError{time.Now(),"it didn't work"}
}

func main() {
    err := run()
    if err != nil {
        //fmt 包在输出时也会试图调用 `error` 接口的Error()方法
        fmt.Println(err)
    }
}

捕捉异常

  • 当发生像数组下标越界或类型断言失败这样的运行错误时,Go 运行时会触发运行时 panic,伴随着程序的崩溃抛出一个 runtime.Error 接口类型的值

  • 我们可以手动调用panic来抛出一个异常使程序停止

package main

import "fmt"

func main() {
    fmt.Println("Starting the program")
    panic("A severe error occurred: stopping the program!")
    fmt.Println("Ending the program")
}

中止程序

  • 当发生错误,该错误非常严重时,必须中止程序,我们可以使用panic 用于错误处理模式
if err != nil {
    panic(“ERROR occurred:” + err.Error())
}

从异常中恢复

  • 我们可以使用recover内建函数来从panic中回复,让程序可以停止终止过程进而恢复正常执行,示例如下:
package main

import "fmt"

func main() {
    protect(g)
}

func protect(g func()) {
    defer func() {
        fmt.Println("done")
        if err := recover(); err != nil {
            fmt.Printf("run time panic: %v", err)
        }
    }()
    fmt.Println("start")
    g()
}

func g() {
    fmt.Println("方法开始")
    panic("发生了一个异常")
    fmt.Println("方法结束")
}
  • 我们需要注意以下几点

1、recover 只能在 defer 修饰的函数中使用
2、如果是正常执行,调用 recover 会返回 nil,且没有其它效果

  • 通过使用 defer-panic-recover 的方式,我们是可以实现类似于try catch 的结构

  • 下面的代码会导致死循环,请思考下为什么?
package main

import (
    "fmt"
)

type ErrNegativeSqrt float64

func (e ErrNegativeSqrt) Error() string {
    if e < 0 {
        return fmt.Sprintf("cannot Sqrt negative number: %v", e)
    }
    return ""
}

func Sqrt(x float64) (float64, error) {
    err := ErrNegativeSqrt(x)
    return x, err

}

func main() {
    fmt.Println(Sqrt(2))
    fmt.Println(Sqrt(-2))
}

你可能感兴趣的:(Go,学习笔记)