ホームページ バックエンド開発 Golang Go言語のエラータイプは何ですか?

Go言語のエラータイプは何ですか?

Jan 12, 2023 am 11:09 AM
golang 言語を移動

Go 言語では、エラーはインターフェイスの種類です。エラー インターフェイス タイプは、エラー処理の標準モードです。関数がエラーを返す場合、戻り値のタイプ リストにはエラーが含まれている必要があります。エラー処理プロセスは C 言語のエラー コードに似ており、層ごとに返すことができます。加工されています。エラー インターフェイス タイプは、メソッドを 1 つだけ含む Error() 文字列として定義され、このインターフェイスを実装するすべてのタイプをエラー タイプとして使用できます。

Go言語のエラータイプは何ですか?

このチュートリアルの動作環境: Windows 7 システム、GO バージョン 1.18、Dell G3 コンピューター。

Go エラーとは、プログラムの実行中に設計プロセスと矛盾する状況によって引き起こされる人為的または自動のフィードバック メカニズムを指します。一部のエラーは意図的に設計されており、エラー処理が追加されたり、処理を待つためにユーザーにフィードバックが与えられたりする場合があります。たとえば、除数が 0 にチェックされている場合はエラーが報告され、ユーザーが問題を認識できるようになります。彼自身の入力の別の例は、指定されたページ情報をクロールすることです。コードでネットワーク切断が発生しました。その他のエラーは、範囲外の配列アクセス添字、クラッシュにつながるヌル ポインタ操作など、不適切なプログラミングによって引き起こされたバグでした。さまざまな状況に合わせて適切に設計されたエラー処理は、成熟したコードの兆候の 1 つであり、これには経験の蓄積や慎重な設計も必要です。

Go 言語のエラーの種類

Go のエラーは、インターフェースの型である error で表され、通常は return と一緒に宣言されます。価値。

エラー処理はすべてのプログラミング言語の重要な部分です。通常、開発中に遭遇する例外とエラーには 2 種類ありますが、Go 言語も例外ではありません。

C 言語では、エラーは -1 や NULL などの戻り値で表現されますが、ユーザーにとっては、対応する API ドキュメントを確認しないと、この戻り値が実際に何を意味するのかわかりません。たとえば、0 を返すのは成功ですか、それとも失敗ですか?

この状況に対応して、Go 言語ではエラー処理の標準モードとしてエラー インターフェイス型が導入され、関数がエラーを返す場合、戻り値の型リストにはエラーが含まれなければなりません。エラー処理プロセスは C 言語のエラー コードに似ており、処理されるまでレイヤーごとに返すことができます。

エラー インターフェイス タイプは、メソッドを 1 つだけ含む Error() 文字列として定義されます。このインターフェイスを実装するすべての型は、エラー型として扱うことができます。 Error() メソッドはエラーの説明を提供します。これは、すべてのデータ型にエラー型を装備できることを意味します。

//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.
ログイン後にコピー

エラー タイプの定義を理解するには、特に *DNSError を参照してください。 *DNSError には 5 つのフィールド構造が含まれます。 Err はエラー テキストを示し、Name はサーバー サーバーによって使用されるクエリのドメイン名、IsTimeout と IsTemporary はエラーの原因を示す 2 つのブール値です。これを詳しく理解するには、次の例を使用してください。

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]
ログイン後にコピー

上記の使用例では、クエリが失敗した場合 (つまり、ポインタが nil でない場合)、型アサーションが行われます。それが *net.DNSError ポインタの場合、構造体フィールドが出力され、エラーが出力され、それ以外の場合はドメイン名とアドレスが出力されます。定義された 2 種類のエラーのうち、上記のクエリはいずれも返しませんでしたが、確かにエラーであったことがわかります。

同時に、 func (e *DNSError) Error() 文字列の定義が return "look " e.Name e.Err であることも推測できます。

エラーの作成

Go の内部エラー フィードバックは次のように定義されています。新しいエラー タイプを定義する方法。

  • 構造を定義し、エラー インターフェイスを実装します。

新しい構造を作成し、上記の DNSError をモデル化して、保存が必要なエラー この構造は、エラーインターフェースを同時に実装することで実装できます。

  • error.New() 関数

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 は、 string を 1 つだけ含む構造体タイプであり、以下を実装します。エラー インターフェイス。New() 関数は、エラーを説明する文字列で errorString を初期化し、構造体のアドレスを返すだけです。これにより、構造体を作成せずに単純なエラー タイプをいつでも直接呼び出すことができ、インターフェイスを実装してメソッド 1 を使用できるようになります。必要。

  • fmt.Errorf() を使用してエラー インターフェイスを返す

fmt.Errorf() 関数シグネチャ: func Errorf ( format string, a ...interface{}) エラー。フォーマットされた文字列を使用し、上記のメソッドを使用して署名を返します。 func Sprintf(format string, a ...interface{}) string、fmt.Errorf() 実装は error.New(fmt.Sprintf(format string, a ...interface{}))# のみを返すことをまだ覚えていますか? # ##########エラー処理#########

当写一个库时,如果发生一个错误,一种方式就是按照上述所说,抛出一个错误,由上层或用户去决断如何处理,是退出还是提示修改;另一种方式就是抛出 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视频教程编程教学

以上がGo言語のエラータイプは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

GOの浮動小数点番号操作に使用されるライブラリは何ですか? GOの浮動小数点番号操作に使用されるライブラリは何ですか? Apr 02, 2025 pm 02:06 PM

GO言語の浮動小数点数操作に使用されるライブラリは、精度を確保する方法を紹介します...

Go's Crawler Collyのキュースレッドの問題は何ですか? Go's Crawler Collyのキュースレッドの問題は何ですか? Apr 02, 2025 pm 02:09 PM

Go Crawler Collyのキュースレッドの問題は、Go言語でColly Crawler Libraryを使用する問題を調査します。 �...

GO言語の「VAR」と「タイプ」キーワード定義構造の違いは何ですか? GO言語の「VAR」と「タイプ」キーワード定義構造の違いは何ですか? Apr 02, 2025 pm 12:57 PM

GO言語で構造を定義する2つの方法:VARとタイプのキーワードの違い。構造を定義するとき、GO言語はしばしば2つの異なる執筆方法を見ます:最初...

GOのどのライブラリが大企業によって開発されていますか、それとも有名なオープンソースプロジェクトによって提供されていますか? GOのどのライブラリが大企業によって開発されていますか、それとも有名なオープンソースプロジェクトによって提供されていますか? Apr 02, 2025 pm 04:12 PM

大企業または有名なオープンソースプロジェクトによって開発されたGOのどのライブラリが開発されていますか? GOでプログラミングするとき、開発者はしばしばいくつかの一般的なニーズに遭遇します...

Redisストリームを使用してGO言語でメッセージキューを実装する場合、user_idタイプの変換の問題を解決する方法は? Redisストリームを使用してGO言語でメッセージキューを実装する場合、user_idタイプの変換の問題を解決する方法は? Apr 02, 2025 pm 04:54 PM

redisstreamを使用してGo言語でメッセージキューを実装する問題は、GO言語とRedisを使用することです...

Goでは、Printlnとstring()関数を備えた文字列を印刷すると、なぜ異なる効果があるのですか? Goでは、Printlnとstring()関数を備えた文字列を印刷すると、なぜ異なる効果があるのですか? Apr 02, 2025 pm 02:03 PM

Go言語での文字列印刷の違い:printlnとstring()関数を使用する効果の違いはGOにあります...

Golandのカスタム構造ラベルが表示されない場合はどうすればよいですか? Golandのカスタム構造ラベルが表示されない場合はどうすればよいですか? Apr 02, 2025 pm 05:09 PM

Golandのカスタム構造ラベルが表示されない場合はどうすればよいですか?ゴーランドを使用するためにGolandを使用する場合、多くの開発者はカスタム構造タグに遭遇します...

Golang Generic Function Typeの制約がVSCodeで自動的に削除されるという問題を解決する方法は? Golang Generic Function Typeの制約がVSCodeで自動的に削除されるという問題を解決する方法は? Apr 02, 2025 pm 02:15 PM

VSCODEユーザーのGolang Generic Function Typeの制約の自動削除は、VSCODEを使用してGolangコードを書くときに奇妙な問題に遭遇する可能性があります。いつ...

See all articles