遅延使用の明確化
はじめに
Go で遅延関数を使用する場合、次のことが重要です。関数のパラメータと戻り値がどのように処理されるかを理解します。この記事は、特定のシナリオでの defer の使用法を明確にすることを目的としています。
問題
defer ステートメントを使用して数値を出力する次の関数について考えてみましょう。
func printNumbers() { var x int defer fmt.Println(x) for i := 0; i < 5; i++ { x++ } }
予想通り、x は for ループが実行される前に評価され保存されるため、関数は完了時に「0」を出力するはずです。ただし、x の最終値を出力する必要があるシナリオもあるでしょう。
解決策
この問題に対処するには、いくつかのアプローチがあります。
1.匿名関数:
defer func() { fmt.Println(x) }()
このソリューションでは、メイン関数の完了後に匿名関数が呼び出されます。 x は匿名関数のパラメーターではないため、関数の実行時に評価され、x.
2 の最終値が反映されます。ポインタ:
var x int defer Print(&x) // Function exists which prints the pointed value for i := 0; i < 5; i++ { x++ }
ポインタを使用すると、x の値ではなくアドレスを遅らせることができます。これにより、遅延には更新されたアドレスが保持されるため、x の最終値が確実に出力されます。
3.カスタム タイプ:
type MyInt int func (m *MyInt) String() string { return strconv.Itoa(int(*m)) } var x MyInt defer fmt.Println(&x) for i := 0; i < 5; i++ { x++ }
fmt.Stringer インターフェイスを実装するカスタム タイプを作成すると、defer ステートメントが値を出力する方法を制御できます。この例では、String() メソッドにより、x の最終値が確実に出力されます。
4.ラッピング:
x := []int{0} defer fmt.Println(x) for i := 0; i < 5; i++ { x[0]++ }
x をスライスでラップすると、for ループの完了後にスライス記述子がコピーされて fmt.Println() 関数に渡されることが保証されます。記述子は同じ基になるデータを参照するため、x の最終値が出力されます。
結論
効果的に使用するには、遅延の仕組みを理解することが不可欠です。上記で概説したアプローチを利用すると、関数パラメーターの評価を延期し、目的の値を確実に出力できます。
以上がGo の遅延関数で変数の最終値を確実に出力するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。