非零基础自学Golang
文章目录
- 非零基础自学Golang
- 第10章 错误处理
- 10.1 错误处理的方式
- 10.2 自定义错误
- 10.2.1 错误类型
- 10.2.2 创建错误
- 10.2.3 自定义错误格式
第10章 错误处理
我们在编写程序时,为了加强程序的健壮性,往往会考虑到对程序中可能出现的错误和异常进行处理。
Go语言设计者认为类似try-catch-finally的传统异常处理机制很容易造成开发者对异常机制的滥用,从而使代码结构变得混乱。
因此,在Go语言中会使用多值返回来返回错误。这种检查错误的方式给程序员提供了很大的控制权。
10.1 错误处理的方式
我们首先来观察下ioutil包中的ReadFile方法,代码如下:
当然现在 已经弃用了
但是笔者还是找到了 源代码:https://cs.opensource.google/go/go/+/refs/tags/go1.6.4:src/io/ioutil/ioutil.go
func ReadFile(filename string) ([]byte, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
defer f.Close()
// It's a good but not certain bet that FileInfo will tell us exactly how much to
// read, so let's try it but be prepared for the answer to be wrong.
var n int64
if fi, err := f.Stat(); err == nil {
// Don't preallocate a huge buffer, just in case.
if size := fi.Size(); size < 1e9 {
n = size
}
}
// As initial capacity for readAll, use n + a little extra in case Size is zero,
// and to avoid another allocation after Read has filled the buffer. The readAll
// call will read into its allocated internal buffer cheaply. If the size was
// wrong, we'll either waste some space off the end or reallocate as needed, but
// in the overwhelmingly common case we'll get it just right.
return readAll(f, n+bytes.MinRead)
}
我们通常使用该函数来打开指定路径下的文件。
ReadFile方法包含两个返回值,类型分别为[]byte和error。我们通过error类型的返回值来判断方法调用是否产生错误,若值为nil,则调用未产生错误。
打开文件的代码如下:
[ 动手写 10.1.1]
package main
import (
"fmt"
"io/ioutil"
)
func main() {
f, err := ioutil.ReadFile("test.txt")
if err != nil {
fmt.Println(err)
} else {
fmt.Println(f)
}
}
运行结果:
由于源代码所在文件夹下没有test.txt文件,系统未找到指定的文件,因此使用ReadFile函数读取文件失败。
这也是Go语言编程中最常见的错误处理方式之一。
10.2 自定义错误
10.2.1 错误类型
Go语言的error类型实际上是一个接口,定义如下:
type error interface {
Error() string
}
error接口包含Error方法,用来返回一个字符串。换言之,所有符合Error()string格式的方法,都能实现错误接口。【果然,天下 语言一家亲】
10.2.2 创建错误
Go语言标准库中的errors包可以用来创建错误,自定义错误内容,格式如下:
err := errors.New("this is an error")
我们使用errors包的New函数来创建自定义错误,代码如下:
[ 动手写 10.2.1]
package main
import (
"errors"
"fmt"
)
func main() {
err := errors.New("this is an error.")
var err2 error
fmt.Println(err.Error())
fmt.Println(err2)
}
运行结果
从执行结果可知:error的类型变量在声明后其默认值为nil。
10.2.3 自定义错误格式
标准库中的fmt包提供了Errorf方法,用来设置返回错误内容的格式,其源码如下:
func Errorf(format string, a ...interface{}) error {
return errors.New(Sprintf(format, a...))
}
我们可以发现Errorf方法本质上还是调用了errors包的New方法来创建了一个错误,并使用Sprintf方法来对错误进行格式化。
[ 动手写 10.2.2 ]
package main
import (
"fmt"
"runtime"
)
func main() {
if _, _, line, ok := runtime.Caller(0); ok == true { // 错误所在位置
err := fmt.Errorf("***Line %d error***", line)
fmt.Println(err.Error())
}
}
运行结果
在程序中,我们通过调用runtime包的Caller方法获取当前代码所在行数,用来模拟错误的产生。