Go 语言入门指南:基础语法和常用特性解析 | 豆包MarsCode AI刷题

86 阅读4分钟

Go 语言入门指南:基础语法和常用特性解析

学到高质量编程内容,记录一下其中的错误处理部分。

error接口类型

在Go语言中,错误处理是使用error接口来完成的。error是一个内置的接口类型,定义在Go的标准库中

type error interface {
    Error() string
}

这个接口非常简单,只有一个Error()方法,该方法返回一个描述错误的字符串。在go当中任何实现了该接口的类型都被称之为错误类型,也可以直接定义一个MyError结构体并实现该方法

1.错误处理

在Go中,错误通常作为函数的最后一个返回值返回。调用者应该检查这个返回值来确定是否发生了错误

value, err := someFunction()
if err != nil {
    // 错误处理逻辑
    log.Println("发生错误:", err)
    return
}
// 使用value继续处理
2.错误链(Chaining)

错误链是错误包装的一个变体,它允许你创建一个错误链,每个错误都包含前一个错误的上下文

err := doSomething()
if err != nil {
    return fmt.Errorf("在doSomething中发生错误: %w", err)
}
3. 错误处理最佳实践
  • 不要忽略错误,即使你认为它不可能发生。
  • 尽可能地提供详细的错误信息。
  • 考虑错误应该被处理还是向上传递。
  • 使用错误包装来添加上下文信息,而不是覆盖原始错误。

errors.New()方法

简单错误指的是仅出现一次的错误,而且在其他地方不需要捕捉。当你需要在代码中表示一个简单错误时,可以使用 errors.New 来创建一个新的错误对象。这个对象可以被返回给调用者,或者用于其他错误处理逻辑。

func New(text string) error  // 返回值是实现了error接口的对象
​
result,err := divide(10,0)
fmt.Println("Error:",err) // fmt包对error类型进行了特殊处理,可以直接打印

你有一个实现了 error 接口的对象时,你可以像处理其他错误一样处理它,比如打印错误消息、根据错误类型做出决策等。由于 error 接口只要求有一个 Error 方法,因此你可以根据需要为错误类型添加额外的字段和方法,以满足你的特定需求。

错误的Wrap和Unwrap

错误的wrap是指提供了一个error嵌套到另一个error上的能力 可以利用fmt.Errorf中使用%w关键字来将一个错误关联到另一个错误中

return fmt.Errorf("reading srcfiles list: %w",err) // 返回的是一个错误对象
errors.As()方法

errors.As 函数用于判断一个错误是否为特定的类型。如果错误确实是该类型,则 errors.As 会将其转换为该类型的值(通过指针参数)。这对于处理具有特定字段或方法的自定义错误类型非常有用。

if errors.As(err, &myErr) {  // 断言成功则将err的值存入myErr中
        fmt.Println("The error is of type *MyError:", myErr.Msg)
    } else {
        fmt.Println("The error is not of type *MyError.")
    }

panic()函数

  • 当程序出现不可逆转的错误时,可以使用panic
  • 调用单数不包含panic会造成程序的崩溃

panic的作用

  1. 中断执行:当panic被调用时,它会立即中断当前函数的执行,并停止正常的控制流。
  2. 执行defer语句:在panic触发后,Go运行时系统会立即执行当前goroutine中所有已注册的defer语句。这些defer语句通常用于进行必要的清理操作,如关闭文件、释放资源等。
  3. 打印堆栈信息:panic会打印出调用堆栈信息,这有助于开发者定位问题发生的位置和原因。堆栈信息详细记录了程序崩溃时的状态和panic触发的调用路径。
  4. 程序崩溃:如果没有通过recover函数捕获panic,程序将崩溃并终止运行

recover()函数

主要用于从panic状态中恢复程序的执行

  • recover只能在当前的goruoutine当中生效
  • defer语句的执行是后进先出的
  • 恢复执行recover() 可以在 defer 修饰的函数中捕获由 panic 触发的异常,并允许程序从异常点恢复执行,而不是直接崩溃退出。
  • 返回值:如果 recover()defer 函数中被调用,且当前有 panic 正在发生,recover() 会返回传递给 panic 的值。如果没有 panic 发生,recover() 会返回 nil

学习总结


目前感觉Go中存在许多C++语言中不存在的特性,如切片、错误类型、接口类,代码写起来有不小的区别,不过语法简洁好上手,学起来比C/C++有意思许多。