Rumah > Artikel > pembangunan bahagian belakang > Mengapakah `defer func() { fmt.Println(i) }()` mencetak "44444" dalam Go, manakala `defer func(n int) { fmt.Println(n) }(i)` mencetak "43210" dengan betul ?
Panggilan Fungsi Tertunda dan Tangkapan Penutupan
Dalam Go, pernyataan penangguhan membenarkan kami melaksanakan fungsi sejurus sebelum fungsi sekeliling kembali. Satu aspek penting penangguhan ialah cara ia mengendalikan penutupan.
Dalam coretan kod ini:
package main import "fmt" func main() { var whatever [5]struct{} for i := range whatever { fmt.Println(i) } // part 1 for i := range whatever { defer func() { fmt.Println(i) }() // part 2 } for i := range whatever { defer func(n int) { fmt.Println(n) }(i) // part 3 } }
Bahagian 1 hanya mencetak nilai i dari 0 hingga 4. Bahagian 2, bagaimanapun, menunjukkan tingkah laku yang menarik. Daripada mencetak nilai jangkaan 0 hingga 4, ia mengeluarkan "44444."
Ini kerana penutupan dalam bahagian 2 menangkap pembolehubah i. Apabila penutupan dilaksanakan kemudian, pembolehubah i mempunyai nilai yang dimilikinya dalam lelaran terakhir pernyataan julat, iaitu 4. Akibatnya, semua fungsi tertunda memanggil cetakan 4.
Sebaliknya, sebahagian 3 tidak menangkap sebarang pembolehubah luar. Menurut spesifikasi Go, "setiap kali pernyataan 'tunda' dilaksanakan, nilai fungsi dan parameter untuk panggilan dinilai seperti biasa dan disimpan semula tetapi fungsi sebenar tidak digunakan." Ini bermakna setiap panggilan fungsi tertunda mempunyai nilai parameter 'n' yang berbeza, iaitu nilai 'i' pada masa pernyataan 'tunda' dilaksanakan.
Oleh itu, bahagian 3 dengan betul mencetak "43210" kerana panggilan fungsi tertunda dilaksanakan dalam susunan LIFO (masuk terakhir, keluar dahulu) sebelum fungsi sekeliling kembali.
Adalah penting untuk diingat bahawa ungkapan fungsi dalam 'menunda f()' tidak dilaksanakan pada masa penyataan penangguhan dilaksanakan, manakala ungkapan dalam 'menunda f(e)' dinilai serta-merta.
Atas ialah kandungan terperinci Mengapakah `defer func() { fmt.Println(i) }()` mencetak "44444" dalam Go, manakala `defer func(n int) { fmt.Println(n) }(i)` mencetak "43210" dengan betul ?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!