Rumah >pembangunan bahagian belakang >Golang >Memanggil tangguh dalam gelung untuk - adakah terdapat cara yang lebih baik untuk menangguhkan membaca respons daripada saluran?

Memanggil tangguh dalam gelung untuk - adakah terdapat cara yang lebih baik untuk menangguhkan membaca respons daripada saluran?

王林
王林ke hadapan
2024-02-09 12:15:221209semak imbas

在 for 循环中调用 defer - 是否有更好的方法来延迟从通道读取响应?

Tangguhkan panggilan dalam gelung untuk - adakah cara yang lebih baik untuk menangguhkan membaca respons daripada saluran? Ini adalah masalah biasa yang dihadapi oleh ramai pembangun apabila menggunakan bahasa Go. Kata kunci tangguh digunakan untuk menangguhkan pelaksanaan fungsi dalam bahasa Go Menggunakan tunda dalam gelung untuk boleh memastikan bahawa operasi tertentu dilakukan selepas setiap gelung berakhir. Walau bagaimanapun, jika anda perlu membaca respons daripada saluran setiap gelung, menggunakan penangguhan mungkin bukan pilihan terbaik. Jadi, adakah cara yang lebih baik untuk menangguhkan membaca respons daripada saluran? Mari kita terokai bersama-sama.

Kandungan soalan

Saya cuba memanggil fungsi yang mengembalikan saluran dalam gelung. Kemudian tambahkan saluran itu pada kepingan channelslice. Akhir sekali, ulangi hirisan saluran dan cetak respons untuk setiap saluran. Apabila saya melakukan ini, IDE saya memaparkan amaran:

possible resource leak, 'defer' is called in the 'for' loop

Seperti yang anda lihat, saya memanggil close(channelslice[i]) di dalam gelung kedua. Adakah ini tidak disyorkan? Selain itu, bagaimanakah ini boleh menyebabkan kebocoran sumber? Adakah terdapat cara yang lebih baik untuk mengendalikan saluran penutupan atau penghirisan?

package main


import (
    "fmt"
    "math/rand"
)

func t() chan int {
    c := make(chan int)
    go func() {
        c <- rand.Intn(100)
    }()

    return c
}

func main() {
    channelSlice := make([]chan int, 0)
    for i := 0; i<100; i++ {
        // Keep making concurrent calls
        // Will read responses from the channel later
        channelSlice = append(channelSlice, t())
    }

    for i := 0; i<100; i++ {
        defer close(channelSlice[i]) // Warning thrown by IDE
        fmt.Println(<-channelSlice[i])
    }
}

Penyelesaian

Seperti yang ditunjukkan oleh @mkopriva,

Panggilan tertunda dilaksanakan apabila fungsi sekeliling keluar, ia tidak dipanggil apabila blok tidak berfungsi di sekeliling keluar. Bungkus badan gelung dalam penutup.

Ini yang saya lakukan:

for i := 0; i<100; i++ {
        func() {
            defer close(channelSlice[i])
            fmt.Println(<-channelSlice[i])
        }()
    }

Seperti yang anda boleh lihat, saya membungkus penyataan defer dalam iife (ungkapan fungsi yang digunakan serta-merta). Ia juga bagus untuk menjadikannya sebagai penutup.

Ini memastikan saluran kini akan ditutup dan tiada kebocoran memori akan berlaku.

Atas ialah kandungan terperinci Memanggil tangguh dalam gelung untuk - adakah terdapat cara yang lebih baik untuk menangguhkan membaca respons daripada saluran?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam