1.介绍

Gotry...catchdefer+recover+panic

2. error接口

2.1 语法

error
type error interface {
  Error() string
}

2.2 函数返回错误

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

2.3 判断错误

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

2.4 创建error对象几种方式

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

errorsNew()errorErrorf()
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 自定义错误的实现步骤

error接口:Error() stringerror

3.2 使用示例

4.延迟函数(defer)

4.1 概念

defer

4.2 在函数中使用

deferdeferdefer
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(崩溃)

panicpanic()PHPthrow

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]
*/
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 介绍

Gotry...catchpanicGorecover
recover()会返回 nilGoroutinerecover()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信息: 错误信息请求失败
*/