英文源地址
在Go中, 习惯上通过显式的单独返回值来传递错误. 这与Java和Ruby等语言中使用的异常以及C语言中的有时使用的重载的单个结果/错误值形参对比.Go的方法可以很容易地看到哪些函数返回了错误, 并使用用于任务其他无错误任务地相同语言结构来处理它们.
package main
import (
"errors"
"fmt"
)
// 依照惯例, error是函数地最后一个返回值, 类型为error, 这是一个内置接口
func f1(arg int) (int, error) {
if arg == 42 {
// errors.New使用给定的错误信息构建一个基础的error值
return -1, errors.New("can't work with 42")
}
// error位置的nil值表示没有错误发生
return arg + 3, nil
}
// 通过在自定义类型上实现Error()方法, 可以将它们用作错误.
// 下面是上面示例的一个变体, 它使用自定义类型显式表示参数错误.
type argError struct {
arg int
prob string
}
func (e *argError) Error() string {
return fmt.Sprintf("%d - %s", e.arg, e.prob)
}
func f2(arg int) (int, error) {
if arg == 42 {
// 在本例中, 我们使用&argError语法构建一个新结构体, 为arg和prob两个字段提供值
return -1, &argError{arg, "Can't work with it"}
}
return arg + 3, nil
}
func main() {
// 下面两个循环测试每个返回错误的函数.
// 请注意, 在if行中使用内联错误检查是Go代码中的常见用法习惯.
for _, i := range []int{7, 42} {
if r, e := f1(i); e != nil {
fmt.Println("f1 failed:", e)
} else {
fmt.Println("f1 worked:", r)
}
}
for _, i := range []int{7, 42} {
if r, e := f2(i); e != nil {
fmt.Println("f2 failed:", e)
} else {
fmt.Println("f2 worked:", r)
}
}
// 如果希望以编程方式在自定义错误中使用数据, 则需要通过类型断言将error作为在自定义错误类型的实例来获取
_, e := f2(42)
if ae, ok := e.(*argError); ok {
fmt.Println(ae.arg)
fmt.Println(ae.prob)
}
}
$ go run errors.go
f1 worked: 10
f1 failed: can't work with 42
f2 worked: 10
f2 failed: 42 - can't work with it
42
can't work with it
更多关于Go的错误处理细节, 可以查看此博客.
下一节将介绍: Goroutines协程