Heim  >  Artikel  >  Backend-Entwicklung  >  Was ist der Fehlertyp in der Go-Sprache?

Was ist der Fehlertyp in der Go-Sprache?

青灯夜游
青灯夜游Original
2023-01-12 11:09:522945Durchsuche

In der Go-Sprache ist Fehler ein Schnittstellentyp. Der Fehlerschnittstellentyp ist ein Standardmodus für die Fehlerbehandlung. Wenn die Funktion einen Fehler zurückgibt, muss die Liste der Rückgabewerttypen einen Fehler enthalten. Der Fehlerverarbeitungsprozess ähnelt dem Fehlercode in der C-Sprache und kann Schicht für Schicht zurückgegeben werden es wird verarbeitet. Der Fehlerschnittstellentyp ist als Error()-String definiert, der nur eine Methode enthält; alle Typen, die diese Schnittstelle implementieren, können als Fehlertyp verwendet werden.

Was ist der Fehlertyp in der Go-Sprache?

Die Betriebsumgebung dieses Tutorials: Windows 7-System, GO Version 1.18, Dell G3-Computer.

Go-Fehler beziehen sich auf menschliche oder automatische Feedbackmechanismen, die durch Situationen verursacht werden, die während der Programmausführung nicht mit dem Designprozess vereinbar sind. Einige Fehler werden absichtlich entworfen und eine Fehlerbehandlung hinzugefügt, oder dem Benutzer wird eine Rückmeldung gegeben, damit er auf die Verarbeitung wartet. Wenn beispielsweise der Divisor auf 0 gesetzt ist, wird ein Fehler gemeldet, damit der Benutzer das Problem erkennen kann Ein weiteres Beispiel ist das Crawlen der angegebenen Seiteninformationen. Bei anderen Fehlern handelte es sich um Fehler, die durch fehlerhafte Programmierung verursacht wurden, z. B. durch Array-Zugriffsoperationen, die zu Abstürzen führten. Eine gut konzipierte Fehlerbehandlung für verschiedene Situationen ist eines der Merkmale ausgereiften Codes und erfordert außerdem gesammelte Erfahrung oder sorgfältiges Design.

Go-Sprachfehlertyp

Go-Fehler wird durch Fehler dargestellt und ist ein Schnittstellentyp, der normalerweise zusammen mit dem Rückgabewert deklariert wird.

Fehlerbehandlung ist ein wichtiger Bestandteil jeder Programmiersprache. Normalerweise gibt es zwei Arten von Ausnahmen und Fehlern, die bei der Entwicklung auftreten, und die Go-Sprache ist keine Ausnahme.

In der C-Sprache werden Fehler durch die Rückgabe von Informationen wie -1 oder NULL ausgedrückt. Wenn Benutzer jedoch nicht die entsprechende API-Dokumentation überprüfen, wissen sie nicht, was der Rückgabewert bedeutet, z. B. die Rückgabe von 0 Erfolg oder Fehler ?

Angesichts dieser Situation wird der Fehlerschnittstellentyp in der Go-Sprache als Standardmodus für die Fehlerbehandlung eingeführt. Wenn die Funktion einen Fehler zurückgibt, muss die Liste der Rückgabewerttypen einen Fehler enthalten. Der Fehlerverarbeitungsprozess ähnelt dem Fehlercode in der C-Sprache und kann Schicht für Schicht zurückgegeben werden, bis er verarbeitet wird.

Der Fehlerschnittstellentyp ist als Error()-String definiert, der nur eine Methode enthält. Alle Typen, die diese Schnittstelle implementieren, können als Fehlertyp behandelt werden. Die Methode Error() liefert eine Beschreibung des Fehlers. Das bedeutet, dass alle Datentypen mit Fehlertypen ausgestattet werden können.

//The error built-in interface type is the conventional interface for representing an error condition, with the nil value representing no error. 
type error interface {
    Error() string
}
//DNSError represents a DNS lookup error. 
type DNSError struct {
    Err         string // description of the error
    Name        string // name looked for
    Server      string // server used
    IsTimeout   bool   // if true, timed out; not all timeouts set this
    IsTemporary bool   // if true, error is temporary; not all errors set this; added in Go 1.6
}

func (e *DNSError) Error() string

func (e *DNSError) Temporary() bool
//Temporary reports whether the DNS error is known to be temporary. This is not always known; a DNS lookup may fail due to a temporary error and return a DNSError for which Temporary returns false. 

func (e *DNSError) Timeout() bool
//Timeout reports whether the DNS lookup is known to have timed out. This is not always known; a DNS lookup may fail due to a timeout and return a DNSError for which Timeout returns false.

Schauen Sie sich speziell *DNSError an, um die Definition eines Fehlertyps zu verstehen. *DNSError enthält 5 Feldstrukturen. Err beschreibt den Fehlertext, Name ist der Domänenname der Abfrage, der vom Serverserver verwendet wird, und IsTimeout und IsTemporary sind zwei boolesche Größen, die die Fehlerursache angeben. Nutzen Sie die folgenden Beispiele, um dies im Detail zu verstehen.

func main() {
    name := "www.ilydsssss.com"
    addr, err := net.LookupHost(name)
    if errS, ok := err.(*net.DNSError); ok {
        fmt.Printf("%+v\n", *errS)
        fmt.Println(err)
    } else {
        fmt.Println(name, addr)
    }  
}
/* result for
------www.ilydsssss.com------------
{Err:no such host Name:www.ilydsssss.com Server: IsTimeout:false IsTemporary:false}
lookup www.ilydsssss.com: no such host

------------ www.iloveyou.com------------
{Err:getaddrinfow: This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server. Name:www.iloveyou.com Server: IsTimeout:false IsTemporary:false}
lookup www.iloveyou.com: getaddrinfow: This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server.
传说中的发送DNS,没有返回的结果,原因你懂的, 这个是什么站点,noidea

----------- www.baidu.com ------------
www.baidu.com [180.97.33.108 180.97.33.107]

Wenn die Abfrage im obigen Anwendungsfall fehlschlägt (d. h. der Zeiger ist nicht Null), wird eine Typzusicherung erstellt. Wenn es sich um einen *net.DNSError-Zeiger handelt, wird das Strukturfeld gedruckt und ein Fehler ausgegeben ; andernfalls werden der Domainname und die Adresse gedruckt. Es ist ersichtlich, dass die obige Abfrage von den beiden definierten Fehlertypen keinen zurückgegeben hat, es sich jedoch tatsächlich um einen Fehler handelte.

Gleichzeitig können Sie auch vermuten, dass die Definition der Zeichenfolge func (e *DNSError) Error() return „look“ + e.Name + e.Err ist.

Fehlererstellung

Gos interne Fehlerrückmeldung wird auf diese Weise definiert. So definieren Sie einen neuen Fehlertyp.

  • Definieren Sie die Struktur und implementieren Sie die Fehlerschnittstelle.

Erstellen Sie eine neue Struktur, modellieren Sie den obigen DNSError, um eine Struktur zu erstellen, die Fehler speichern muss, und implementieren Sie gleichzeitig die Fehlerschnittstelle erreicht.

  • error.New()-Funktion

package errors
// New returns an error that formats as the given text.
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
}

errorString ist ein Strukturtyp, der nur einen String enthält und die Fehlerschnittstelle implementiert. Die New()-Funktion wird einfach mit einem String initialisiert, der den Fehler errorString beschreibt, und gibt zurück die Adresse der Struktur, wodurch ein einfacher Fehlertyp jederzeit direkt aufgerufen werden kann, ohne dass eine Struktur erstellt und die Schnittstelle implementiert werden muss. Verwenden Sie ggf. Methode 1.

  • Verwenden Sie fmt.Errorf(), um die Fehlerschnittstelle zurückzugeben.

fmt.Errorf() Funktionssignatur: func Errorf(format string, a ...interface{}) Fehler, der ein formatiertes Zeichen verwendet String gibt mit der oben genannten Methode eine Signatur zurück. Erinnern Sie sich noch daran, dass die Implementierung von func Sprintf(format string, a ...interface{}) string, fmt.Errorf() nur error.New(fmt.Sprintf(format string, a ...interface{})) zurückgibt?

Fehlerbehandlung

当写一个库时,如果发生一个错误,一种方式就是按照上述所说,抛出一个错误,由上层或用户去决断如何处理,是退出还是提示修改;另一种方式就是抛出 panic 来终止程序,除非遇到特别严重的错误,什么叫严重呢?就是程序已经没有执行的必要了,莫不如抛出错误,直接退出。有两种情况可以考虑使用 panic: 1. 发生了一个不能恢复的错误,此时程序不能继续运行。2. 存在一个编程上的错误。

当程序由 panic 引发终止时,可以使用 recover 重新获取该程序控制权。panic 和 recover 与其他语言中的 try-catch-finally 语句类似,只不过一般我们很少使用 panic 和 recover。

内建函数 panic 的签名为:func panic(interface{}),此处接口为空接口,也可以理解为任意数据类型都可以输入,输入什么,则提示什么。

func div(x, y int) float64 {
    defer fmt.Println("DIV ......")
    if y == 0 {
        panic(fmt.Sprintf("%d / %d, 除数为零, 无法计算", x, y))
    }
    return float64(x) / float64(y)
}
fmt.Println(div(3, 0))
/* result
panic: 3 / 0, 除数为零

goroutine 1 [running]:
main.div(0x3, 0x0, 0x2)
        error.go:10 +0x148
main.main()
        error.go:25 +0x15a
exit status 2
*/

从上述例子可以看到,当函数发生 panic 时,它会终止运行,在执行完所有的延迟函数后,程序控制返回到该函数的调用方。这样的过程会一直持续下去,直到当前协程的所有函数都返回退出,然后程序会打印出 panic 信息,接着打印出堆栈跟踪,最后程序终止。

recover 是一个内建函数,用于重新获得 panic 协程的控制。recover 函数的标签如下所示:func recover() interface{}。需要注意的是:只有在延迟函数的内部,调用 recover 才有用。在延迟函数内调用 recover,可以取到 panic 的错误信息,并且停止 panic 续发事件,程序运行恢复正常。如果在延迟函数的外部调用 recover,就不能停止 panic 续发事件。

例如:

import (
    "runtime/debug"
)
func recoverFdiv() {
    if r := recover(); r != nil {
        fmt.Println("来自 DIV 的恢复, 除数为零,下面是出错log记录")
        debug.PrintStack()
    }
}

func div(x, y int) float64 {
    defer recoverFdiv()
    if y == 0 {
        panic(fmt.Sprintf("%d / %d, 除数为零, 无法计算", x, y))
    }
    return float64(x) / float64(y)
}
fmt.Println(div(3, 0))

/* result
来自 DIV 的恢复, 除数为零,下面是出错log记录
goroutine 1 [running]:
runtime/debug.Stack(0xc000072008, 0xc00006fd68, 0x1)
        runtime/debug/stack.go:24 +0xae
runtime/debug.PrintStack()
        runtime/debug/stack.go:16 +0x29
main.recoverFdiv()
        D:/ZHY-L/OneDrive/文档/开发/goblog/myerror.go:12 +0x89
panic(0x4b9620, 0xc000030040)
        runtime/panic.go:513 +0x1c7
main.div(0x3, 0x0, 0x0)
        error.go:19 +0x186
main.main()
        error.go:34 +0x15a
0
*/

如上所示,调用延迟函数 recoverFdiv(),它使用了 recover() 来停止 panic 续发事件,主函数还是继续执行了。同时,利用debug.PrintStack() 打印了 panic 记录,这样在保证程序继续执行的同时,也留下了调试宝贵的记录。

同理,Go 内置的运行时错误(如数组越界)也会导致 panic。这等价于调用了内置函数 panic,其参数由接口类型 runtime.Error 给出。runtime.Error 接口的定义如下:

type Error interface {  
    error
    // RuntimeError is a no-op function but
    // serves to distinguish types that are run time
    // errors from ordinary errors: a type is a
    // run time error if it has a RuntimeError method.
    RuntimeError()
}

【相关推荐:Go视频教程编程教学

Das obige ist der detaillierte Inhalt vonWas ist der Fehlertyp in der Go-Sprache?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn