Rumah >pembangunan bahagian belakang >Golang >Mengapakah Gelung `untuk julat` Go Mempamerkan Gelagat Berbeza dengan Huruf Fungsi?

Mengapakah Gelung `untuk julat` Go Mempamerkan Gelagat Berbeza dengan Huruf Fungsi?

Susan Sarandon
Susan Sarandonasal
2024-12-10 20:52:11422semak imbas

Why Does Go's `for range` Loop Exhibit Different Behavior with Function Literals?

Memahami Gelagat Berbeza dalam Go

Apabila membina gelung dalam Go, adalah penting untuk memahami gelagat gelung untuk julat. Pertimbangkan dua variasi gelung berikut yang menunjukkan gelagat yang berbeza:

Variasi Gelung 1:

func loop1() {

    actions := make(map[string]func())

    for _, cmd := range cmds {
        actions[cmd] = func() {
            fmt.Println(cmd)
        }
    }
    for _, action := range actions {
        action()
    }
}

Variasi Gelung 2:

func loop2() {

    actions := make(map[string]func())

    for i, cmd := range cmds {
        command := cmds[i]
        actions[cmd] = func() {
            fmt.Println(command)
        }
    }
    for _, action := range actions {
        action()
    }
}

Output Pemerhatian:

  • Gelung1 menghasilkan output: "kemas kini" (diulang 3 kali)
  • Gelung2 menghasilkan output: "padam", "kemas kini", "buat"

Isu Asas dalam Variasi Gelung 1:

Masalahnya terletak pada gelung func loop1(). Setiap lelaran gelung memberikan fungsi literal kepada peta tindakan. Fungsi ini secara literal merujuk kepada pembolehubah gelung cmd. Walau bagaimanapun, terdapat hanya satu contoh cmd, dan apabila gelung selesai, ia memegang nilai terakhir dalam kepingan arahan, iaitu "kemas kini." Ini bermakna semua fungsi yang disertakan merujuk pembolehubah gelung (cmd) yang sama, yang menyebabkan semua fungsi mencetak "kemas kini" apabila dipanggil.

Penyelesaian:

Untuk membetulkan ini , buat salinan pembolehubah gelung dalam setiap lelaran gelung, jadi setiap fungsi literal mempunyai bebasnya sendiri copy:

func loop1() {
    actions := make(map[string]func())

    for _, cmd := range cmds {
        cmd2 := cmd
        actions[cmd] = func() {
            fmt.Println(cmd2) // Refer to the detached, copy variable!
        }
    }
    for _, action := range actions {
        action()
    }
}

Kesimpulan:

Kesimpulannya, apabila menggunakan gelung julat for, adalah penting untuk mempertimbangkan skop dan rujukan pembolehubah gelung. Memastikan salinan pembolehubah gelung dibuat apabila perlu memastikan gelagat yang betul, terutamanya apabila berurusan dengan literal fungsi yang merujuk pembolehubah tersebut.

Atas ialah kandungan terperinci Mengapakah Gelung `untuk julat` Go Mempamerkan Gelagat Berbeza dengan Huruf Fungsi?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn