ホームページ >バックエンド開発 >Golang >Go で「defer」が名前付き戻り値に与える影響が入力パラメータとは異なるのはなぜですか?

Go で「defer」が名前付き戻り値に与える影響が入力パラメータとは異なるのはなぜですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-11-29 00:18:12593ブラウズ

Why Does `defer` Affect Named Return Values Differently Than Input Parameters in Go?

Go の変数宣言に対する defer の影響を理解する

Go では、defer キーワードを使用すると、関数が返されるときにコードを実行できます。たとえパニックが起きても。ただし、関数内で変数がさまざまな方法で宣言されている場合、結果が異なる可能性があり、混乱が生じる可能性があります。

消失増分の謎

次のコード スニペットを考えてみましょう。

func c(i int) int {
    defer func() { i++ }()
    return i
}

func main() {
    fmt.Println(c(0)) // Prints 0
}

この例では、c 関数を呼び出し、値 0 を渡します。ただし、結果を出力すると、結果ではなく 0 が返されます。 1 が期待されます。これは、i が関数への入力パラメーターとして宣言されているためです。 return ステートメントが実行されると、defer 関数が呼び出されますが、インクリメントは戻り値には影響しません。

名前付き結果の魔法

前の例とは対照的に、次のことを考えてみましょう。次のコード:

func c1() (i int) {
    defer func() { i++ }()
    return i
}

func main() {
    fmt.Println(c1()) // Prints 1
}

ここで、i は c1 関数の結果パラメーターとして宣言されています。 return ステートメントが実行されると、i の値が戻り値に設定されます。ただし、defer 関数は、値が返される前に i の値を変更することができます。この結果、出力は 1 になります。

明示的な戻りと遅延変更

この動作をさらに詳しく説明するために、別の例を追加してみましょう。

func c2() (i int) {
    defer func() { i++ }()
    return 2
}

func main() {
    fmt.Println(c2()) // Prints 3
}

この例では、 return ステートメントは、defer 関数が呼び出される前に i を明示的に 2 に設定します。その結果、defer 関数は i の値をインクリメントし、戻り値は 3 になります。

名前付き結果パラメーターの威力

これらの例から重要な点は、入力パラメーターの違いです。そして名前付き結果パラメータ。入力パラメータは関数に渡されますが、名前付き結果パラメータは関数の戻り値を保持する変数です。 Defer 関数は、return ステートメントの実行後に名前付き結果パラメーターを変更できますが、入力パラメーターには影響しません。

以上がGo で「defer」が名前付き戻り値に与える影響が入力パラメータとは異なるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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