لغة Go بالأمثلة: إغلاق القنوات (close)

يشير إغلاق قناة إلى عدم إرسال أي قيم أخرى إليها. يفيد ذلك في إبلاغ مستقبِلي القناة باكتمال العمل.

package main
import "fmt"

سنستخدم في هذا المثال القناة jobs لإرسال العمل المطلوب من روتين Go الذي ينفذ main() إلى روتين Go عامل. عندما لا يبقى لدينا المزيد من المهام للعامل، سنغلق القناة jobs باستخدام close.

func main() {
    jobs := make(chan int, 5)
    done := make(chan bool)

هذا هو روتين Go العامل. يستقبل مرارًا من jobs باستخدام j, more := <-jobs. في صيغة الاستقبال الخاصة هذه، التي تعيد قيمتين، تكون قيمة more مساوية لـfalse إذا أُغلقت jobs واستُقبلت جميع القيم الموجودة في القناة. نستخدم ذلك للإشعار عبر done بعد إنجاز جميع مهامنا.

    go func() {
        for {
            j, more := <-jobs
            if more {
                fmt.Println("received job", j)
            } else {
                fmt.Println("received all jobs")
                done <- true
                return
            }
        }
    }()

يرسل هذا 3 مهام إلى العامل عبر القناة jobs، ثم يغلقها.

    for j := 1; j <= 3; j++ {
        jobs <- j
        fmt.Println("sent job", j)
    }
    close(jobs)
    fmt.Println("sent all jobs")

ننتظر العامل باستخدام أسلوب المزامنة الذي رأيناه سابقًا.

    <-done

تنجح القراءة من قناة مغلقة فورًا، وتعيد القيمة الصفرية للنوع الأساسي. تكون قيمة الإرجاع الثانية الاختيارية true إذا وصلت القيمة المستقبلة بعملية إرسال ناجحة إلى القناة، أو false إذا كانت قيمة صفرية أُنشئت لأن القناة مغلقة وفارغة.

    _, ok := <-jobs
    fmt.Println("received more jobs:", ok)
}
$ go run closing-channels.go 
sent job 1
received job 1
sent job 2
received job 2
sent job 3
received job 3
sent all jobs
received all jobs
received more jobs: false

تقودنا فكرة القنوات المغلقة طبيعيًا إلى مثالنا التالي: استخدام range لاجتياز القنوات.

المثال التالي: .