ホームページ  >  記事  >  バックエンド開発  >  Go言語でのdeferの使い方は何ですか?

Go言語でのdeferの使い方は何ですか?

王林
王林オリジナル
2021-01-07 15:23:134817ブラウズ

Go 言語での defer の使用法: 1. defer ステートメントは関数が戻る前、または関数内の return ステートメントの後に実行されます; 2. 複数の defer ステートメントの実行順序は逆順になります; 3.パニック ステートメントの後で遅延 ステートメントは実行されません。

Go言語でのdeferの使い方は何ですか?

#この記事の動作環境: Windows10 システム、GO 1.11.2、thinkpad t480 コンピューター。

(学習ビデオの共有: プログラミング ビデオ)

使用法の紹介:

defer は Go 言語の遅延実行ステートメントであり、関数の終わり 実行時に実行されるコード。多くの場合、割り当てられた特定のリソースの解放、データベース接続のクローズ、ソケット接続の切断、およびロックされたリソースのロック解除に使用されます。 Go 言語のメカニズムは、defer ステートメント内のコードが実行されることを保証します。

Java や C# の Final ステートメントなど、他の言語にも同様のメカニズムがあり、C 言語のデストラクターも同様の役割を果たすことができます。C 言語のメカニズムでは、オブジェクトが破棄される前に必ず破棄されることが保証されます。デストラクタ内のコードが実行されます。 C のデストラクターはオブジェクトを破壊し、Go の defer は関数を破壊します。

1. defer 文の実行タイミング

defer 文は、関数が戻る前、または関数内の return 文の後に実行されます (return 文は別の関数を呼び出す場合があります)。サンプル コード:

package main
 
import (
    "fmt"
)
 
func main() {
    fmt.Println(deferReturn())
}
 
func deferReturn() (ret int) {
    defer func() {
        ret++
    }()
    return 10
}

上記のコードによって出力される値は次のとおりです: 11.無名関数の defer ステートメントの「ret」は、戻り値 10 に 1 を加えて 11 になります。 return ステートメントの後に defer ステートメントが出現するコードを見てみましょう:

func returnDefer() (ret int) {
    return 0
    defer func() {
        ret++
        ret++
    }()
    return 1
}

上記の returnDefer 関数の戻り値は 0 です。その理由は、コードを追加して「return 0」関数を実行する前に defer ステートメントが戻るため、defer ステートメントは実行されないためです。

2. 複数の defer ステートメントの実行順序は逆順です

複数の defer ステートメントが出現する場合、それらは逆の順序で実行されます (スタックと同様、つまり後入れ先出し) )。サンプル コード:

func deferSample() {
    for i := 0; i < 5; i++ {
        defer fmt.Printf("%d ", i)
    }
}

上記のコードの出力: 4 3 2 1 0

3. Defer と Panic

1. Panic ステートメントの後の defer ステートメントは、

サンプル コード:

func panicDefer() {
    panic("panic")
    defer fmt.Println("defer after panic")
}

上記のコードの出力は次のとおりです:

panic: panic
goroutine 1 [running]:
main.panicDefer()
    E:/godemo/testdefer.go:17 +0x39
main.main()
    E:/godemo/testdefer.go:13 +0x20
Process finished with exit code 2

defer ステートメントが実行されていないことがわかります。

2. パニック ステートメントが実行される前の defer ステートメント

サンプル コード:

func deferPanic() {
    defer fmt.Println("defer before panic")
    panic("panic")
}

上記のコードの出力は次のとおりです:

defer before panic
panic: panic
goroutine 1 [running]:
main.deferPanic()
    E:/godemo/testdefer.go:19 +0x95
main.main()
    E:/godemo/testdefer.go:14 +0x20
Process finished with exit code 2

defer ステートメントの出力内容。

Go のパニックは、他の言語で例外をスローするのと似ており、パニック後のコードは実行されなくなります (パニック ステートメントの前の defer ステートメントが実行されます)。

4. return の実装ロジック

1. 最初のステップは、戻り値に値を割り当てることです (名前付き戻り値が直接割り当てられている場合は、匿名戻り値が最初に宣言されます)そして割り当てられます);
2. 2 番目のステップでは、RET return 命令を呼び出し、戻り値を渡します。RET は defer ステートメントがあるかどうかを確認します。存在する場合は、最初に defer ステートメントを逆に挿入します。 order;
3. 最後に、RET は戻り値を返して関数を終了します。

return はアトミック操作ではなく、関数の戻り値が RET の戻り値と必ずしも一致しないことがわかります。

5. defer、return、return value の順序

defer、return、return value の実行順序は次のとおりです: return は最初に戻り値に値を割り当て、次に defer が始まります。最後の仕上げ Work を実行し、最後に RET 命令が戻り値を返して関数を終了します。

関連する推奨事項: golang チュートリアル

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

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