错误是指程序中出现不正常的情况,从而导致程序无法正常运行Go语言中没有try...catch来捕获错误,而是通过defer recover panic模式来实现捕捉错误信息,我来为大家讲解一下关于go功能注释介绍?跟着小编一起来看一看吧!

go功能注释介绍(Go学习十五:异常处理)

go功能注释介绍

1.介绍

错误是指程序中出现不正常的情况,从而导致程序无法正常运行。Go语言中没有try...catch来捕获错误,而是通过defer recover panic模式来实现捕捉错误信息。

2. error接口2.1 语法

Go语言通过内置的错误类型提供了非常简单的错误处理机制,即error接口。该接口的定义如下:

type error interface { Error() string }

2.2 函数返回错误

对于大多数函数,如果要返回错误,大致上都可以定义为如下模式,必须将error作为多种返回值中的最后一个。

// 函数返回错误 func Demo(参数列表...)(x T, err error){ // 函数体 }

2.3 判断错误

在Go语言中处理错误的方式通常是将返回的错误与nil进行比较。nil值表示没有发生错误,而非nil值表示出现错误。如果不是nil,需打印输出错误。

x,err := Demo(参数列表...) if err != nil { // 打印错误信息.... }

2.4 创建error对象几种方式

常见的创建error对象的几种方式:

package main import ( "errors" "fmt" ) func main() { // 方式一: 使用errors包下的New() err := createError(1) printError(err) // 方式二: 使用fmt包下的Errorf() err2 := createError(2) printError(err2) } func printError(err error){ if err != nil{ fmt.Printf("err==> %v | err.Error() ==> %v | 类型==> %T \n",err,err.Error(),err) } } // 创建error对象 func createError(way int) error { if way == 1 { // 方式一: 使用errors包下的New() return errors.New("方式一: 使用errors包下的New() ") } else if way == 2 { // 方式二: 使用fmt包下的Errorf() return fmt.Errorf("方式二: 使用fmt包下的Errorf(...) ---> ") } return nil } /**输出 err==> 方式一: 使用errors包下的New() | err.Error() ==> 方式一: 使用errors包下的New() | 类型==> *errors.errorString err==> 方式二: 使用fmt包下的Errorf(...) ---> | err.Error() ==> 方式二: 使用fmt包下的Errorf(...) ---> | 类型==> *errors.errorString */

3.自定义错误3.1 自定义错误的实现步骤3.2 使用示例

package main import ( "fmt" "time" ) // 第一步: 定义一个结构体 type MyError struct { msg string t time.Time } // 第二步: 并实现error接口 func (m MyError) Error() string { return fmt.Sprintf("错误信息: %s 发生时间: %v", m.msg, m.t) } // 第三步: 定义一个返回error的函数 func login(phone, pwd string) (bool, error) { if phone == "17600000111" && pwd == "123456" { return true,nil } err := MyError{"账号密码错误!", time.Now()} return false,err } func main() { // 测试 res,err := login("17600000111","123789") if err != nil { fmt.Printf("登录失败--> %v T --> %T \n", err.Error(), err) } else { fmt.Printf("登录成功 --> %v \n", res) } res2,err2 := login("17600000111","123456") if err2 != nil { fmt.Printf("登录失败--> %v T --> %T \n", err2.Error(), err2) }else { fmt.Printf("登录成功 --> %v \n", res2) } } /**输出 登录失败--> 错误信息: 账号密码错误! 发生时间: 2020-11-27 16:09:39.774176 0800 CST m= 0.000091945 T --> main.MyError 登录成功 --> true */

4.延迟函数(defer)4.1 概念

关键字defer用于延迟一个函数或者方法(或者当前所创建的匿名函数)的执行。defer语句只能出现在函数或方法的内部。

4.2 在函数中使用

在函数中可以添加多个defer语句。如果有很多调用defer,当函数执行到最后时,这些defer语句会按照逆序执行(报错的时候也会执行),最后该函数返回。

package main import "fmt" func main() { // 测试 defer defer1() defer defer2(4,6) defer defer2(40,60) // 匿名函数 defer func() { fmt.Println("匿名函数defer3....") }() // 函数正常处理代码 for i:= 1; i<4 ; i { fmt.Println(i) } } // 无参数的函数 func defer1() { fmt.Println("函数defer1....") } // 有参数的函数 func defer2(a,b int) { fmt.Printf("函数defer2....a=%d b= %d a b=%d \n",a,b,a b) } /**输出 1 2 3 匿名函数defer3.... 函数defer2....a=40 b= 60 a b=100 函数defer2....a=4 b= 6 a b=10 函数defer1.... */

defer语句经常被用于处理成对的操作,如打开-关闭、连接-断开连接、加锁-释放锁。特别是在执行打开资源的操作时,遇到错误需要提前返回,在返回前需要关闭相应的资源,不然很容易造成资源泄露等问题。

5.panic(崩溃)

panic让当前的程序进入恐慌,中断程序的执行。panic()是一个内建函数,可以中断原有的控制流程。其功能类似于PHP中的throw。

5.1 造成panic的场景1.数组访问越界

package main import "fmt" func main() { // 测试访问数组下标越界 arr := [3]int{1,2,3} // 数组下标最大为2 fmt.Println(arr[3]) } /** 报错 ./main.go:9:17: invalid array index 3 (out of bounds for 3-element array) */

2.访问未初始化的指针或 nil 指针

package main import "fmt" func main() { // 测试-> 访问未初始化的指针或 nil 指针 // 1.定义一个指针类型(默认值是nil) var b *int fmt.Println(b) // 2.访问nil的指针 fmt.Println(*b) } /** 报错 <nil> panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x10a6ef8] */

3.向已经 close 的 chan(管道) 里发送数据

package main func main() { // 测试->往已经 close 的 `chan`(管道) 里发送数据 // 1.声明一个管道 var ch = make(chan int,1) // 2.关闭管道 close(ch) // 3.向已关闭管道写入数据 ch <- 1 } /** 报错 panic: send on closed channel */

4.类型断言

package main import "fmt" func main() { // 测试->类型断言错误 var i interface{} = "hello" a := i.([]string) fmt.Println(a) } /**报错 panic: interface conversion: interface {} is string, not []string */

5.2 使用

package main import "fmt" func main() { throw("请求成功!",1) throw("请求失败!",0) } func throw(msg string,code int) { if code == 0 { panic("报错信息: " msg) } fmt.Println("正确输出:" msg) } /** 输出 正确输出:请求成功! panic: 报错信息: 请求失败! goroutine 1 [running]: main.throw(0x10cce7a, 0xd, 0x0) /Users/hui/Project/Go/src/go-basic/main.go:12 0x145 main.main() /Users/hui/Project/Go/src/go-basic/main.go:7 0x65 Process finished with exit code 2 */

6.recover(恢复)6.1 介绍

Go语言中没有try...catch来捕获错误,一旦触发panic就会导致程序崩溃。在Go中是通过recover让程序恢复。值的注意的是recover()必须在延迟函数(defer)中有效。

在正常的程序运行过程中,调用 recover()会返回 nil,并且没有其他任何效果。如果当前的Goroutine陷入恐慌,调用recover()可以捕获panic()的输入值,使程序恢复正常运行。

6.2 使用

package main import "fmt" func main() { // 定义一个匿名延迟函数 defer func() { err := recover() msg := fmt.Sprintf("err信息: %v",err) if err != nil { // 程序触发panic时,会被这里捕获 fmt.Println(msg) } }() // 定义一个数组 testPanic("请求失败") } // 故意抛出panic func testPanic(err string) { panic("错误信息" err) } /** 输出 err信息: 错误信息请求失败 */

微信搜索【猿码记】,获取最新文章信息。

,