"进阶架构师" 微信公众号,欢迎大家订阅、阅读、评论、点赞!!!!
前言
今天,我们来聊一下,Golang中那些不能说的错误和异常。
青春常在,学习不变的信仰,加油所有人。
错误是与语言无关的部分,有助于以不会发生意外情况的方式编写代码。如果发生某种形式的某种方式不支持的错误,则会发生错误。错误有助于编写简洁的代码,从而增加程序的可维护性。
错误
错误是一个完善的抽象概念,它在发生异常时发生。也就是说,每当发生意外情况时,都会引发错误。错误在每种语言中都很常见,这基本上意味着它是编程领域中的一个概念。
思考下,我们在学习Java时,学习的异常错误体系。Java语言的异常处理框架,是Java语言健壮性的一个重要体现。让我们来复习下,Java中的异常错误。
Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。 在Java API中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception。 Java异常体系结构呈树状,其层次结构图如图 1所示:
图 1 Java异常体系结构
Thorwable类所有异常和错误的超类,有两个子类Error和Exception,分别表示错误和异常。 其中异常类Exception又分为运行时异常(RuntimeException)和非运行时异常, 这两种异常有很大的区别,也称之为不检查异常(Unchecked Exception) 和检查异常(Checked Exception)。
1、Error与Exception
Error是程序无法处理的错误,比如OutOfMemoryError、ThreadDeath等。这些异常发生时, Java虚拟机(JVM)一般会选择线程终止。
Exception是程序本身可以处理的异常,这种异常分两大类运行时异常和非运行时异常。 程序中应当尽可能去处理这些异常。
2、运行时异常和非运行时异常
运行时异常都是RuntimeException类及其子类异常,如NullPointerException、IndexOutOfBoundsException等, 这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的, 程序应该从逻辑角度尽可能避免这类异常的发生。
非运行时异常是RuntimeException以外的异常,类型上都属于Exception类及其子类。 从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。 如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。
GoLang中的错误
GoLang以非常简单的方式支持错误。Go函数将错误返回为第二个返回值。这是在Go中实现和使用错误的标准方法。这意味着可以在继续下一步之前立即检查错误。
错误显示创建
有多种创建错误的方法。在这里,我们将讨论可以轻松创建的简单代码。
1.使用新建功能
GoLang错误包具有一个称为**New()**的函数,可用于轻松创建错误。
package main
import (
"fmt"
"errors"
)
func e(v int) (int, error) {
if v == 0 {
return 0, errors.New("Zero cannot be used")
} else {
return 2*v, nil
}
}
func main() {
v, err := e(0)
if err != nil {
fmt.Println(err, v) // Zero cannot be used 0
}
}
2.使用Errorf函数
fmt软件包具有Errorf()方法,该方法允许格式化错误,如下所示。
fmt.Errorf("Error: Zero not allowed! %v", v) // Error: Zero not allowed! 0
错误检查
要检查错误,我们只需获取函数的第二个值,然后使用nil来检查该值。由于错误的零值为nil。因此,我们检查错误是否为零。如果是,则没有错误发生,并且在所有其他情况下都发生了错误。
package main
import (
"fmt"
"errors"
)
func e(v int) (int, error) {
return 42, errors.New("42 is unexpected!")
}
func main() {
_, err := e(0)
if err != nil { // check error here
fmt.Println(err) // 42 is unexpected!
}
}
异常抛出与处理
开发过程中,我们需要对异常进行抛出,且同时需要,进行处理。类似于Java的
Try catch。
package main
import (
"fmt"
)
func f(s string) {
panic(s) // throws panic
}
func main() {
// defer makes the function run at the end
defer func() { // recovers panic
if e := recover(); e != nil {
fmt.Println("Recovered from panic")
}
}()
f("Panic occurs!!!") // throws panic
// output:
// Recovered from panic
}
创建自定义错误
就如之前,我们创建错误展示的方式,可以通过函数errors.New()和fmt.Errorf()创建新错误。另外,我们仍然可以有另一种方式来创建自定义错误,那就是实现错误接口。
type CustomError struct {
data string
}
func (e *CustomError) Error() string {
return fmt.Sprintf("Error occured due to... %s", e.data)
}
错误返回
GoLang开发中,实现错误返回比较简单。不像Java中似的,需要特殊处理。
Go中通过返回值实现错误返回。Go支持多个返回值,因此我们可以同时返回任何值和错误,然后检查错误。
import (
"fmt"
"errors"
)
func returnError() (int, error) { // declare return type here
return 42, errors.New("Error occured!") // return it here
}
func main() {
v, e := returnError()
if e != nil {
fmt.Println(e, v) // Error occured! 42
}
}
错误忽略
有些情况下,程序在执行过程中,我们需要跳过返回的错误。那就是GoLang中错误的忽略。
在Go中,具有skip(-)运算符,实现忽略GoLang中的错误。
package main
import (
"fmt"
"errors"
)
func returnError() (int, error) { // declare return type here
return 42, errors.New("Error occured!") // return it here
}
func main() {
v, _ := returnError() // skip error with skip operator
fmt.Println(v) // 42
}
总结
哈哈,今天的课程又要结束了。我们今天学习了,在Go中如何实现异常与错误,以及其相关的操作。同时也对比复习了Java中的异常错误体系结构。我们可以对比着学习,相信很容易就能掌握。
加油加油,每一个爱人。