Ekspresi Lambda menyediakan cara ringkas untuk mentakrifkan fungsi sebaris dalam gelung. Walau bagaimanapun, menggunakan pembolehubah lelaran secara langsung dalam lambdas boleh membawa kepada tingkah laku yang tidak dijangka kemudian.
Perangkap Lambda pembolehubah lelaran:
Pertimbangkan kod berikut:
<code class="language-c#">for (int i = 0; i < 10; i++) { Action action = () => Console.WriteLine(i); actions.Add(action); } foreach (var action in actions) { action(); }</code>
Orang mungkin berfikir bahawa setiap lambda akan mencetak nilai yang sepadan bagi i. Walau bagaimanapun, disebabkan penutupan, semua lambda berkongsi rujukan ditangkap yang sama kepada i.
Hasil cetakan yang tidak dijangka:
Apabila gelung keluar, i menjadi 10 dan semua lambda kini menunjuk ke nilai akhir ini. Akibatnya, melaksanakan lambda akan mencetak "10" sepuluh kali dan bukannya urutan yang dijangkakan dari 0 hingga 9.
Tingkah laku ini terhasil daripada penutupan lambda yang mengekalkan rujukan kepada pembolehubah yang diisytiharkan dalam skopnya, walaupun selepas gelung telah selesai.
Pengelak dan alternatif:
Untuk menyelesaikan masalah ini, buat pembolehubah tempatan dalam gelung dan tetapkan nilai pembolehubah lelaran:
<code class="language-c#">for (int i = 0; i < 10; i++) { int j = i; // 创建一个局部变量 Action action = () => Console.WriteLine(j); actions.Add(action); } foreach (var action in actions) { action(); }</code>
Ini memastikan setiap lambda menangkap nilai j yang berbeza, menghasilkan urutan cetakan yang dijangkakan.
Perlu diingat bahawa menggunakan pembolehubah lelaran secara langsung dalam ungkapan lambda mungkin membawa kepada keadaan berkaitan penutupan yang tidak dijangka. Sebaliknya, pertimbangkan untuk mencipta pembolehubah tempatan untuk menangkap nilai yang anda perlukan dengan tepat.
Atas ialah kandungan terperinci Mengapa Ungkapan Lambda Menangkap Nilai Akhir Pembolehubah Lelaran, dan Bagaimanakah Ini Boleh Dielakkan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!