前言
今天,我们来聊一下,Golang中那些不能说的错误和异常。
青春常在,学习不变的信仰,加油所有人。
错误是与语言无关的部分,有助于以不会发生意外情况的方式编写代码。如果发生某种形式的某种方式不支持的错误,则会发生错误。错误有助于编写简洁的代码,从而增加程序的可维护性。
错误
错误是一个完善的抽象概念,它在发生异常时发生。也就是说,每当发生意外情况时,都会引发错误。错误在每种语言中都很常见,这基本上意味着它是编程领域中的一个概念。
思考下,我们在学习Java时,学习的异常错误体系。Java语言的异常处理框架,是Java语言健壮性的一个重要体现。让我们来复习下,Java中的异常错误。
Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。 在Java API中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception。
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中的异常错误体系结构。我们可以对比着学习,相信很容易就能掌握。
加油加油,每一个爱人。