-
一个可能造成错误的函数,需要返回值中返回一个错误接口(error),如果调用是成功的,错误接口将返回 nil,否则返回错误--->Go语言中函数的调用一定会返回调用结果err
-
在函数调用后需要检查错误,如果发生错误,则进行必要的错误处理
Go的异常处理机制和其他语言异常处理机制比较
java
等语言异常处理机制:
try{
}catch{
}finally{
}
Go语言可以使用defer、panic、recover
模拟try...catch...finally
操作。但是官方不主张这样做
Go语言中错误接口的定义格式
error 是 Go 系统声明的接口类型。位于build包下--->Error()方法返回错误的具体描述
type error interface{
Error() string
}
/*
符合Error() string格式的方法都能实现错误接口。
Error()方法返回错误的具体描述
*/
net包和io包error处理例子
net.Dial()
实例:
func Dial(network, address string) (Conn, error) {
var d Dialer
return d.Dial(network, address)
}
/*
dial.go源码包下的函数
*/
io包下writter接口
实例:
type Writer interface {
Write(p []byte) (n int, err error)
}
自定义一个错误
使用 errors 包进行错误的定义
var err = errors.New("this is an error")
/*
错误字符串由于相对固定,一般在包作用域声明,应尽量减少在使用时直接使用 errors.New 返回--->直接使用.New方法返回
*/
errors
包对New
的定义:
// 创建错误对象
func New(text string) error {
return &errorString{text}
}
/*
将 errorString 结构体实例化,并赋值错误描述的成员
*/
// 错误字符串
type errorString struct {
s string
}
/*
声明 errorString 结构体,拥有一个成员,描述错误内容
*/
// 返回发生何种错误
func (e *errorString) Error() string {
return e.s
}
/*
实现 error 接口的 Error() 方法,该方法返回成员中的错误描述
形参是指针e指向结构体errorString。通过这个方式实现接口Error()
*/
示例代码:
package main
import (
"errors"
"fmt"
)
//自定义一个错误
var errorZero = errors.New("division by zero")
/*
定义一个除法函数,被除数除以除数。如果商为0返回错误
*/
func div(dividend, divisor int) (int, error) {
//判断除数为0抛出异常
if divisor == 0 {
return 0, errorZero
}
//正常计算,返回空值
return dividend/divisor, nil //正常计算返回空的error
/*
进行正常的除法计算,没有发生错误时,错误对象返回 nil
*/
}
func main() {
fmt.Println(div(1,0))
}
在解析中使用自定义错误
示例代码:
package main
import "fmt"
/*
声明一个结构体,包含错误的解析
*/
type ParseError struct {
Filename string //文件名
Line int //行号
/*
声明了一个解析错误的结构体,解析错误包含有 2 个成员,分别是文件名和行号
*/
}
/*
声明一个error接口,指向结构体,返回错误的描述
*/
func (e *ParseError) Error() string { //实现了错误接口,将成员的文件名和行号格式化为字符串返回
return fmt.Sprintf("%s,%d", e.Filename, e.Line)
}
//创建一些解析错误??
/*
根据给定的文件名和行号创建一个错误实例--->这是一个错误实例
*/
func newParseError(filename string, line int) error {
return &ParseError{filename, line}
}
func main() {
var e error //声明一个错误接口类型
//创建一个错误实例
e = newParseError("main.go", 1)
/*
创建一个实例,这个错误接口内部是 *ParserError 类型,携带有文件名 main.go 和行号 1
*/
//通过error接口查看错误描述
fmt.Println(e.Error())
//通过断言获取详细的错误信息
switch detail := e.(type) {
case *ParseError: //解析错误
fmt.Printf("Filename: %s Line: %d\n", detail.Filename, detail.Line)
default:
//其他类型的错误
fmt.Println("other error")
}
}
/*
错误对象都要实现 error 接口的 Error() 方法
所有的错误都可以获得字符串的描述
想进一步知道错误的详细信息,可以通过类型断言,将错误对象转为具体的错误类型进行错误详细信息的获取。
*/