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 サイトの他の関連記事を参照してください。