select
الاختيار بين عدّة قنوات select
select يجعل الكود ينتظر أكثر من عملية قناة في نفس الوقت، وينفّذ أول حالة تصبح جاهزة.
select statement يشبه switch لكن كل case فيه عملية قناة (إرسال أو استقبال) بدل قيمة. يحجب select التنفيذ حتى تصبح إحدى الحالات جاهزة للتنفيذ؛ إن كان أكثر من حالة جاهزًا بنفس اللحظة، يختار Go واحدة عشوائيًا بينها لضمان العدالة ومنع تفضيل قناة على أخرى بشكل دائم. ترتيب كتابة الحالات في الكود لا يؤثر على أولويتها.
إضافة حالة default تجعل select غير حاجب: إن لم تكن أي قناة جاهزة فورًا، ينفَّذ default مباشرة بدل الانتظار — مفيد لفحص قناة دون تعليق التنفيذ.
الصياغة
select {
case v := <-ch1:
// ...
case ch2 <- value:
// ...
default:
// اختياري — ينفَّذ إن لم تجهز أي حالة فورًا
}📄 مثال
c1 := make(chan string)
c2 := make(chan string)
go func() {
time.Sleep(time.Second)
c1 <- "من الأولى"
}()
go func() {
time.Sleep(2 * time.Second)
c2 <- "من الثانية"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
fmt.Println(msg1)
case msg2 := <-c2:
fmt.Println(msg2)
}
}أهم النقاط
| العنصر | الوظيفة |
|---|---|
| case <-ch: | حالة استقبال من قناة — تُنفَّذ عندما تصبح جاهزة |
| case ch <- v: | حالة إرسال لقناة — تُنفَّذ عندما يوجد مستقبل جاهز |
| default: | يمنع الحجب — ينفَّذ فورًا إن لم تجهز أي حالة |
💡 نصائح عملية
- ادمج select مع ctx.Done() لإيقاف goroutine عند إلغاء أو انتهاء مهلة context
- select بلا أي حالة جاهزة وبلا default يحجب للأبد — استخدمه عمدًا فقط لهذا الغرض
⚠️ أخطاء شائعة
- توقّع أن الحالة الأولى المكتوبة لها أولوية — Go يختار عشوائيًا بين كل الحالات الجاهزة
- نسيان default في حلقة فحص متكرّرة يسبّب حجب البرنامج بدل الاستمرار
خصائص ذات صلة
🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار GO الكامل بالعربي.