18 错误处理

错误处理基本用法:

package main

import (
	"fmt"
	"math"
)

func sqrt(n float64) (float64, error) {
	if n < 0 {
		return 0, fmt.Errorf("invalid argument '%f', must be >= 0", n)
	}
	return math.Sqrt(n), nil
}

func printSqrt(n float64) {
	if res, err := sqrt(n); err == nil {
		fmt.Printf("sqrt of %f is %f\n", n, res)
	} else {
		fmt.Printf("sqrt of %f returned error '%s'\n", n, err)
	}

}

func main() {
	printSqrt(16)
	printSqrt(-16)
}

// 输出结果
// sqrt of 16.000000 is 4.000000
// sqrt of -16.000000 returned error 'invalid argument '-16.000000', must be >= 0'

跟C#和Python不同,Go的错误处理是直接返回错误值,而不是抛出异常。

Go也提供了恐慌和恢复的异常机制,但它们应该被尽量少用。

错误也是值,就像整数或字符串一样。

error类型是一个内置(built-in)接口类型,该接口规定了Error() string方法。

如果要表示执行成功,则把表示错误的变量置为nil返回。

若要表示执行失败,则把错误变量赋值为errors.New(msg string)fmt.Errorf(format string, args... interface{})返回的值。

您也可以通过自定义一个结构体并实现Error() string方法来自定义错误类型

如果一个函数要返回错误,那么错误值应当总是最后一个。

应始终检查函数的返回值中是否包含错误。编写鲁棒性强的软件的关键就是检查错误并进行适当处理。初学者通常放弃检查错误,然后面临调试神秘故障的麻烦。

译者注:error源码解读

// error接口的定义
// src/builtin/builtin.go
type error interface {
	Error() string
}

// error的实现
// src/errors/errors.go

// New returns an error that formats as the given text.
// Each call to New returns a distinct error value even if the text is identical.
func New(text string) error {
	return &errorString{text}
}

// errorString is a trivial implementation of error.
type errorString struct {
	s string
}

func (e *errorString) Error() string {
	return e.s
}

就这么多,没了。是不是简单到爆。error仅仅是一种普通的interface类型,包含一个返回类型为字符串的Error()函数。

最后更新于