欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Golang 错误处理

程序员文章站 2022-06-24 17:06:19
...

FBI WRINING

文章会牵扯到接口部分的内容,没有接触过的读者建议先去学习。


定义

在go中,错误被定义成一个接口(interface)

type error interface {
    Error() string
}

使用

最简单的使用错误的方法就是用函数创建一个错误

简易版本

package main

import (
	"errors"
	"fmt"
)

func main() {
	value := false
	text, err := isu(value)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(text)
	}
}

func isu(value bool) (string, error) {
	if value == true {
		return "true!!!!! ", nil
	} else {
		return "", errors.New("error! is false! ")
	}
}
error! is false! 

我们先看上面代码的核心部分:isu函数。

函数用if语句判断参数value的值是否为true,为true就返回一个字符串,而错误则为nil(没有错误)。

当为false就返回一个空字符串,而我们用errors里面的New函数(也是errors包里唯一一个函数)创建了一个包含有用信息的错误并返回。

 

转到main函数,我们创建了一个变量,并将他传入到isu函数内,由于变量值为false,所以isu函数将返回一个错误。

最后我们用if判断错误变量是否不为nil(有错误),有错误就输出错误信息。但是这样也造成了大量的样板代码,所以设计者出来挨打

 

 

除了errors包,fmt包里面也提供了类似的函数

package main

import (
	"fmt"
)

func main() {
	value := false
	text, err := isu(value)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(text)
	}
}

func isu(value bool) (string, error) {
	if value == true {
		return "true!!!!! ", nil
	} else {
		return "", fmt.Errorf("error! is %t! ", value)
	}
}
error! is false! 

都是一样的效果。不过他可以更灵活,而不是像最初的例子,字符串是“死”的(硬编码),因此个人也更推荐使用fmt包里的。

 

高级版本

想象一下,如果我们需要更详细的错误信息,比如文件名,你该怎么做?我们当然可以直接分割字符串提取信息,但是谁也不知道这个字符串会不会变,到时候变了就没辙了。

为此,我们可以自己定义一个错误类型,获取更详细的错误信息。

package main

import (
	"fmt"
)

type FileError struct {
	name string
}

func (self *FileError) Error() string {
	return "File Error! "
}

func OpenFile(name string) (int32, error) {
	return -1, &FileError{name}
}

func main() {
	file, err := OpenFile("opengl_init.go")
	if err != nil {
		fmt.Println(err)
		err_type := err.(*FileError)
		fmt.Println(err_type.name)
	} else {
		fmt.Println("File is open. handle: %s ", file)
	}
}
File Error! 
opengl_init.go

在上面的代码里,我们定义了一个类型FileError(文件错误),并为他实现了Error方法来返回一个错误信息,这也代表他真正意义上成为了错误类型。

错误是产生出来的,所以我们需要一个能产生错误的函数。在这里我们定义了一个函数OpenFile(仅供演示,实际肯定是不同的),为了方便演示,我们直接返回错误。由于FileError结构体实现了error接口,所以返回值列表我们可以直接填error。

接着我们使用OpenFile函数,并且检查返回的err是否不为nil,由于我们直接返回了错误,所以if语句的分支我们就不用管了。

最后,我们打印了错误信息,一如既往很正常。重磅的来了!我们对err进行类型断言获得原始类型(*FileError),这样,我们就能访问到FileError结构体,获得文件名了!

相关标签: Go语言 go