Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Perangkap biasa penutupan fungsi golang

Perangkap biasa penutupan fungsi golang

PHPz
PHPzasal
2024-04-23 12:45:02966semak imbas

Terdapat perangkap apabila menggunakan penutupan fungsi dalam Go: Perkongsian pembolehubah: Mengubah suai pembolehubah apabila berbilang penutupan merujuk kepada pembolehubah yang sama akan menjejaskan gelagat semua penutupan. Penukaran jenis pembolehubah: Kemudian menukar jenis pembolehubah tangkapan kepada jenis lain boleh membawa kepada hasil yang tidak dapat diramalkan. Dalam amalan, masalah penutupan fungsi yang menjana jujukan boleh diselesaikan dengan mencipta salinan pembolehubah tempatan untuk setiap penutupan untuk mengelakkan pengubahsuaian pembolehubah yang ditangkap.

Perangkap biasa penutupan fungsi golang

Perangkap biasa penutupan fungsi dalam Go

Dalam Go, penutupan ialah fungsi yang merujuk kepada pembolehubah setempat pada masa penciptaannya. Ia boleh memberikan fleksibiliti program, tetapi jika digunakan secara salah, ia juga boleh memperkenalkan tingkah laku yang tidak dijangka dan masalah yang sukar untuk nyahpepijat.

Perangkap penutupan

Berikut adalah beberapa perangkap penutupan fungsi biasa:

1. Perkongsian pembolehubah

Apabila beberapa penutupan merujuk kepada pembolehubah tempatan yang sama, mengubah suai pembolehubah akan menjejaskan tingkah laku semua penutupan. Contohnya:

func counter() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

// 两个同时调用的闭包共享计数变量
c1 := counter()
c2 := counter()
c1()
c2()

akan menyebabkan nilai yang dikembalikan menjadi 2 dan bukannya 1 dan 2 yang dijangkakan. . Contohnya:

func intToString() string {
    i := 42
    return func() string {
        // 会返回一个空字符串,而不是 "42"
        return strconv.Itoa(i)
    }
}

Oleh kerana pembolehubah yang saya tangkap oleh penutupan ditukar kepada jenis rentetan, strconv.Itoa() tidak boleh ditukar dengan betul. Kes praktikal

Jangkaan:

Buat fungsi yang menjana urutan berdasarkan nombor yang dihantar sehingga nilai maksimum dicapai.

Kod:

func generateSequence(max int) []int {
    seq := []int{}
    i := 0
    return func() int {
        i++
        if i > max {
            return 0
        }
        seq = append(seq, i)
        return i
    }
}

Masalah:

Penutupan fungsi ini menangkap pembolehubah i dan mengubah suainya apabila penutupan dipanggil. Walau bagaimanapun, kami menjangkakan penutupan itu akan mengembalikan nilai i baharu setiap kali ia dipanggil.

Betulkan:

Isu ini boleh diselesaikan dengan membuat salinan pembolehubah setempat untuk setiap penutupan.

func generateSequence(max int) []int {
    seq := []int{}
    return func() int {
        i := 0
        i++
        if i > max {
            return 0
        }
        seq = append(seq, i)
        return i
    }
}

Nota:

Kod tetap tidak lagi mengubah suai pembolehubah i yang ditangkap, tetapi akan mencipta salinan baharu setiap kali.

Atas ialah kandungan terperinci Perangkap biasa penutupan fungsi golang. 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