Keutamaan dalam Penyata Pilih Go
Apabila bekerja dengan berbilang saluran menggunakan kenyataan pilih Go, susunan saluran dikendalikan tidak dijamin. Untuk mengutamakan satu saluran berbanding saluran lain, penyelesaian tersedia.
Pernyataan Masalah
Dalam coretan kod di bawah, matlamatnya adalah untuk memastikan semua nilai dalam saluran keluar diproses sebelum saluran keluar:
package main import "fmt" func sender(out chan int, exit chan bool){ for i := 1; i <= 10; i++ { out <- i } exit <- true } func main(){ out := make(chan int, 10) exit := make(chan bool) go sender(out, exit) L: for { select { case i := <-out: fmt.Printf("Value: %d\n", i) case <-exit: fmt.Println("Exiting") break L } } fmt.Println("Did we get all 10? Most likely not") }
Walau bagaimanapun, menggunakan pernyataan pilih tidak memberikan keutamaan untuk satu saluran berbanding yang lain.
Penyelesaian: Sokongan Bahasa Ibunda
Go secara asli menyokong mengutamakan saluran dalam pernyataan terpilih dengan mengehadkan keterlihatan saluran "berhenti" kepada hanya pengeluar. Apabila pengeluar memutuskan untuk berhenti, ia menutup saluran. Pengguna hanya akan berhenti apabila saluran kosong dan ditutup.
package main import ( "fmt" "math/rand" "time" ) var ( produced = 0 processed = 0 ) func produceEndlessly(out chan int, quit chan bool) { defer close(out) for { select { case <-quit: fmt.Println("RECV QUIT") return default: out <- rand.Int() time.Sleep(time.Duration(rand.Int63n(5e6))) produced++ } } } func quitRandomly(quit chan bool) { d := time.Duration(rand.Int63n(5e9)) fmt.Println("SLEEP", d) time.Sleep(d) fmt.Println("SEND QUIT") quit <- true } func main() { vals, quit := make(chan int, 10), make(chan bool) go produceEndlessly(vals, quit) go quitRandomly(quit) for x := range vals { fmt.Println(x) processed++ time.Sleep(time.Duration(rand.Int63n(5e8))) } fmt.Println("Produced:", produced) fmt.Println("Processed:", processed) }
Dalam contoh ini, saluran berhenti hanya boleh dilihat oleh fungsi pengeluar (produceEndlessly). Pengeluar secara rawak memutuskan untuk berhenti selepas kelewatan tertentu. Fungsi pengguna (utama) berulang melalui saluran vals sehingga ia ditutup dan kosong. Dengan mengutamakan mesej "berhenti" pengeluar, semua nilai dalam saluran vals diproses sebelum program keluar.
Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Mengutamakan Saluran dalam Penyata `pilih` Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!