【Go编程学习】异常处理

目录

异常处理

定义

Panic

源码分析

参考


异常处理

Go 有一个预先定义的 error 接口类型:

type error interface{
    Error() string
}

定义

当需要一个新的错误类型,可以用errors包的new函数接受合适的错误信息创建:

package main

import(
    "errors"
    "fmt"
)

var errTest error = errors.New("test error")

func main() {
    fmt.Printf("error: %v", errTest)
}

 

也可以使用fmt.Errorf()实现:

err := fmt.Errorf("This is an error")
if err != nil {
  fmt.Print(err)
}

除了直接使用Go自带的方法,还可以自定义错误。下面以自然数函数作为例子:

type NotNature float64

func (err NotNature) Error() string {
     return fmt.Sprintf("自然数为大于或等于0的数: %v", float64(err))
}

func Nature(x float64) (float64,error) {
      if x<0 {
           return 0,NotNature(x)
      } else {
          return x,nil
      }
}

func main() {
      fmt.Println(Nature(1))
      fmt.Println(Nature(-1))
}

注意:

  • 如果函数需要处理异常,通常将error作为多值返回的最后一个值,返回的error值为nil则表示无异常,非nil则是有异常。
  • 一般先用if语句处理error!=nil,正常逻辑放if后面。
  • Go语言的error代表的并不是真“异常”,只是通过返回error来表示错误信息,换句话说,不是运行时错误范围预定义的错误,某种不符合期望的行为并不会导致程序无法运行(自然数函数例子),都应使用error进行异常处理。当程序出现重大错误,如数组越界,才会将其当成真正的异常,并用panic来处理。

Panic

Go不使用try...catch方法来处理异常,而是使用panic和recover

例子:

func main() {
      fmt.Println("Hello,Go!")
      panic(errors.New(" i am a error"))
      fmt.Println("hello,again!")
}

/*GOLand输出:
Hello,Go!
panic:  i am a error

goroutine 1 [running]:
main.main()
	test_go.go:10 +0xc5

Process finished with exit code 2

*/

panic之后的程序并没有被执行,recover的作用就是从panic或错误场景中恢复,让程序可以从 panicking 重新获得控制权,停止终止过程进而恢复正常执行:

package main

import "fmt"

func main(){
    //Go 语言的 defer 会在当前函数或者方法返回之前执行传入的函数。
      defer func(){
            fmt.Println("我是defer里面第一个打印函数")
            if err:=recover();err!=nil{
            fmt.Println(err)
        }
        fmt.Println("我是defer里面第二个打印函数")
      }()
      f()
}

func f(){
      fmt.Println("1")
      panic("我是panic")
      fmt.Println("2")
}

/*输出:
1
我是defer里面第一个打印函数
我是panic
我是defer里面第二个打印函数
*/

执行f函数,首先输出1,然后f函数调用panic,停止正常执行,f返回其调用者(main),对调用方来说,对f的调用就像调用panic一样,终止调用方的执行并运行任何延迟的函数。panic 会导致栈被展开直到 defer 修饰的 recover () 被调用或者程序中止。

recover只能在 defer 修饰的函数中使用:用于取得 panic 调用中传递过来的错误值,如果是正常执行,调用recover会返回 nil,且没有其它效果。

defer和recover必须在panic之前定义,否则无效。

源码分析

// src/errors/errors.go

// New returns an error that formats as the given text.
// Each call to New returns a distinct error value even if the text is identical.
func New(text string) error {
	    return &errorString{text}
}

// errorString is a trivial implementation of error.
type errorString struct {
	    s string
}

func (e *errorString) Error() string {
	    return e.s
}

1.New函数返回格式为给定文本的错误

2.即使文本是相同的,每次对New的调用都会返回一个不同的错误值。

参考

https://github.com/datawhalechina/go-talent

Go入门指南

猜你喜欢

转载自blog.csdn.net/i0o0iW/article/details/111597009