Go では、defer キーワードを使用して、周囲の関数が戻るまで関数呼び出しの実行を延期します。遅延呼び出しのパラメーターと関数の値は、defer ステートメントの実行時に通常どおり評価されますが、実際の関数は周囲の関数の return ステートメントの直前に呼び出されます。
評価defer キーワードを使用したステートメントの順序は、後入れ先出し (LIFO) アプローチに従います。たとえば、次のコードについて考えてみましょう。
<code class="go">defer func1()() defer func2()() fmt.Println("main function")</code>
この例では、func1() への呼び出しは延期され、main 関数が返される直前に実行されます。同様に、func2() の呼び出しは延期され、func1() の呼び出しの前に実行されます。
defer の一般的な使用例は、関数が呼び出される前にリソースを自動的に解放することです。関数が戻ります。たとえば、ファイル ハンドルは関数の先頭で開き、関数が戻る前に defer を使用して閉じることができます。
問題の例を考えてみましょう。
<code class="go">defer fmt.Println("Your age is:", getAge(age)) // calls getAge defer fmt.Println("Your ticket price is:", printTicket(age, ticketprice)) // calls printTicket</code>
このコードでは、getAge() の呼び出しは printTicket() の呼び出しよりも先に延期されます。これは、年齢の評価とチケット価格の計算がすぐに行われる一方で、年齢とチケット価格の実際の出力は関数が戻るまで延期されることを意味します。
defer を使用すると、年齢を確実に設定できます。関数の実行中にエラーが発生した場合でも、チケットの価格は常に出力されます。
問題の元のコードには、printTicket 関数が呼び出されないという問題がありました。これは、ticketPrice 変数が宣言されているものの、値が割り当てられていなかったためです。 defer を使用すると、印刷前にチケット価格が正しく計算されることを確認できます。
コードの修正バージョンは次のとおりです:
<code class="go">package main import "fmt" func main() { var age int defer fmt.Println("Your age is:", getAge(&age)) defer fmt.Println("Your ticket price is:", printTicket(age)) } func printTicket(age int) float64 { var ticketPrice float64 switch { case age <= 13: ticketPrice = 9.99 case age > 13 && age < 65: ticketPrice = 19.99 case age >= 65: ticketPrice = 12.99 } return ticketPrice } func getAge(age *int) int { fmt.Println("What is your age?") fmt.Scan(age) for *age < 0 || *age > 100 { fmt.Println("That cannot be, please enter your age again") fmt.Scan(age) } return *age }</code>
この修正により、コードは正しくなります。ユーザーの年齢に基づいてチケット価格を印刷します。
以上がGo では defer キーワードはどのように機能しますか?また、このコード例ではどのような問題が解決されますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。