- 能够产生错误的函数必须返回一个错误接口(error),如果调用成功则返回nil,否则返回错误。
- 您应该在函数调用后检查错误,并在发生错误时执行任何必要的错误处理。
Go 语言没有像 Java 或 .NET 那样的异常处理机制。可以进行延迟、恐慌和恢复模拟,但官方并未推荐。 Go语言的设计者相信其他语言的异常机制是有效的。上面的逻辑被过度使用,需要为函数内部发生的异常付出大量的资源,同时,如果函数的使用者发现错误处理过于繁琐而忽略错误,程序就会在不经意的瞬间崩溃。
Go语言希望开发者将错误处理视为正常开发中必须实现的一个环节,从而正确处理所有可能导致错误的函数。错误的复杂性使得开发人员能够真正掌握错误处理。
net包中的示例
net.Dial() 是 Go 语言系统包 net 中的一个函数,通常用于创建套接字连接。
net.Dial 有两个返回值:Conn 和 error。该函数是阻塞的,在 Socket 操作后返回一个 Conn 连接对象和一个错误。如果发生错误,error 会告诉您错误的类型,并且 Conn 返回空。
根据Go语言的错误处理机制,Conn是一个重要的返回值,因此我们在这个函数中添加了一个类似于error的错误返回值。请参阅下面的代码。
func Dial(network, address string) (Conn, error) {
var d Dialer
return d.Dial(network, address)
} io 包的 Writer 接口也会返回错误。这是代码:
type Writer interface{
Write(p []byte) (n int, err error)
} io 包还有一个 Closer 接口。仅返回一个错误。这是代码:
type Closer interface {
Close() error
} 错误接口定义格式
error是Go系统声明的接口类型,代码为:
type error interface {
Error() string
} Error() 任何符合字符串格式的方法都可以实现错误接口。 Error()方法返回错误的详细描述,让用户通过这个字符串知道发生了什么错误。
自定义错误
在返回错误之前,您需要定义可能发生哪种错误。 Go语言使用errors包来定义错误。格式为:
var err = errors.New("this is an error") 由于错误字符串相对固定,因此它们通常在包范围内声明,并且应最小化,以便在使用errors.New 时直接返回。
1)错误包
在Go语言中定义New错误非常简单,代码如下:
// エラーオブジェクトを作成する
func New(text string) error {
return &errorString{text}
}
// エラー文字列
type errorString struct {
s string
}
// 何が起こったかを返す
func (e *errorString) Error() string {
return e.s
} 代码说明如下:
- 第二行实例化 errorString 结构并为错误描述成员分配一个值。
- 第 7 行声明了 errorString 结构。该结构包含描述错误的成员。
- 第 12 行实现了错误接口的 Error() 方法,并返回成员中错误的描述。
2)您在代码中使用了错误的定义
以下代码定义了一个除法函数,如果除数为 0,则该函数返回预定义的被零除错误。
package main
import (
"errors"
"fmt"
)
// 除数が0のエラーを定義します
var errDivisionByZero = errors.New("division by zero")
func div(dividend、divisor int) (int、error) {
//除数が0の場合は、そのまま返します
if divisor == 0 {
return 0、errDivisionByZero
}
//通常の計算で、空のエラーを返します
return dividend / divisor、nil
}
func main() {
fmt.Println(div(1、0))
} 这是代码输出:
0 division by zero
代码解释:
- 第 9 行,预定义的除以 0 错误。
- 第 11 行声明了一个除法函数,输入被除数和除数,并返回商和误差。
- 第14行,在除法的计算中,如果除数为0,计算结果会无穷大,所以为了避免这种情况,确定了除数,商为0除数为0的错误返回一个对象。
- 第19行执行正常的除法计算,如果没有发生错误,则错误对象返回nil。

error.New中定义的error字符串错误类型无法提供丰富的错误信息,因此如果需要返回错误信息,必须使用自定义结构体实现error接口。
以下代码实现了解析错误(ParseError)。该错误包含两件事:文件名和行号。解析错误结构还实现了错误接口的Error()方法。返回错误描述时,返回文件名和行号。
package main
import(
"fmt"
)
// 解析エラーを宣言する
type ParseError struct {
Filename string // ファイル名
Line int // 行番号
}
// 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)
//エラーの説明をerrorインターフェイスで確認する
fmt.Println(e.Error())
//エラーインターフェイスの具体的なタイプに基づいて、詳細なエラー情報を取得する
スイッチdetail := e.(タイプ) {
case *ParseError: //これはjson解析エラーです。
fmt.Printf("Filename: %s Line: %d\n", detail.Filename, detail.Line)
default: // 他の種類のエラー
fmt.Println("other error")
}
} 这是代码输出:
main.go:1
Filename: main.go Line: 1
代码说明如下:
- 第8行声明了解析错误结构体,其中包含两个成员:文件名和行号。
- 第 14 行实现错误接口并以字符串形式返回成员的文件名和行号。
- 第 19 行根据指定的文件名和行号创建一个错误实例。
- 第 25 行声明错误接口类型。
- 在第 27 行创建了一个实例,其内部错误接口类型为 *ParserError,文件名为 main.go,行号为 1。
- 第 30 行调用 Error() 方法,第 15 行返回错误详细信息。
- 第 33 行通过错误断言检索详细的错误类型。
- 解析第34行的错误类型,发现错误类型为*ParserError,此时可以获得详细的错误信息。
- 如果不是可以处理的错误类型,第 36 行会打印另一个错误以供进一步处理。
错误对象必须实现错误接口的Error()方法。这样你就可以将所有错误写入字符串中。如果您想了解有关错误的更多信息,可以使用类型断言将错误对象转换为:获取特定错误类型的错误详细信息。




![2021 年如何设置 Raspberry Pi Web 服务器 [指南]](https://i0.wp.com/pcmanabu.com/wp-content/uploads/2019/10/web-server-02-309x198.png?w=1200&resize=1200,0&ssl=1)

