English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
في لغة Go، هي قناة وسيلة اتصال بين goroutine وآخر goroutine، وهي اتصال غير مشبك. بمعنى آخر، هي تقنية تسمح لـ goroutine بارسال البيانات إلى goroutine آخر. بشكل افتراضي، القناة ثنائية الاتجاه، مما يعني أن goroutine يمكنه إرسال أو استقبال البيانات من خلال نفس القناة، كما هو موضح في الشكل التالي:
في لغة Go، يتم إنشاء قنوات باستخدام كلمة المفتاح chan، ويمكنها نقل نوع البيانات نفسه فقط، ولا يُسمح بنقل أنواع بيانات مختلفة عبر نفس القناة.
النص:
var Channel_name chan Type
يمكنك أيضًا استخدام تعريف مختصر عبر دالة make() لإنشاء قناة.
النص:
channel_name := make(chan Type)
package main import "fmt" func main() { // استخدام كلمة المفتاح var لإنشاء قناة var mychannel chan int fmt.Println("قيمة القناة:", mychannel) fmt.Printf("نوع القناة: %T", mychannel) // استخدم دالة make() لإنشاء قناة mychannel1 := make(chan int) fmt.Println("\nقيمة قناة channel1:", mychannel1) fmt.Printf("نوع قناة channel1: %T", mychannel1) }
الإخراج:
قيمة القناة: <nil> نوع القناة: chan int قيمة قناة channel1: 0xc0000160c0 نوع قناة channel1: chan int
في لغة Go، تعمل القنوات بثلاث عمليات رئيسية، وهي الإرسال والاستقبال، وتُعرف هذه العمليات بـ "الإتصال". يعكس دالة <- اتجاه البيانات التي يتم إرسالها أو استقبالها. في القنوات، يتم تأخير العمليات حتى لا يكون هناك بيانات في الجانب الآخر بشكل افتراضي. هذا يسمح لـ goroutines بالتواصل مع بعضها البعض دون الحاجة إلى قفل أو متغيرات الحالة المحددة.
عملية الإرسال:استخدام عملية الإرسال لتحويل البيانات من داخل goroutine إلى أخرى بمساعدة قناة. يمكن إرسال القيم مثل int،float64 وbool بسهولة وأمان عبر القنوات لأنها يتم نسخها، مما يعني عدم وجود خطر من الوصول المتوازي إلى نفس القيمة. بالإضافة إلى ذلك، فإن النصوص آمنة أيضًا لأنها غير قابلة للتغيير. ولكن، لا يمكن إرسال الإشارات أو المراجع (مثل المجموعات، المخططات، إلخ) عبر القنوات بطرق آمنة لأن قيم الإشارات أو المراجع قد تتغير عبر عملية الإرسال أو الاستقبال، مما يؤدي إلى نتائج غير قابلة للتنبؤ. لذلك، يجب التأكد من أن الإشارات أو المراجع تستخدم عبر القناة مرة واحدة فقط من قبل goroutine واحدة.
Mychannel <- element
تعني جملة أعلاه أن البيانات (element) في<-باستخدام دالة المساعدة إرسالها إلى القناة (Mychannel).
عملية الاستقبال:استخدام عملية الاستقبال لاستقبال البيانات التي يرسلها الطرف المرسل.
element := <-Mychannel
تعني جملة أعلاه أن العنصر تم استقباله من قناة (Mychannel). إذا كان الناتج من الاستقبال غير متاح (لا يحتاج إلى استخدامه)، فإن الجملة صحيحة أيضًا. يمكنك أيضًا كتابة جملة receive مثل التالية:
<-Mychannel
package main import "fmt" func myfunc(ch chan int) { fmt.Println(234 + <-ch) } func main() { fmt.Println(بداية الطريقة الرئيسية) //إنشاء قناة l ch := make(chan int) go myfunc(ch) ch <- 23 fmt.Println(انتهاء الطريقة الرئيسية) }
الإخراج:
بداية الطريقة الرئيسية 257 انتهاء الطريقة الرئيسية
يمكنك أيضًا إغلاق القناة بمساعدة دالة close(). إنها دالة مدمجة وتضبط علامة تشير إلى أن لا يوجد أي بيانات سيتم إرسالها إلى القناة.
النص:
close()
يمكنك أيضًا استخدام دورة for rangه لإغلاق القناة. هنا، يمكن لمسار المستقبل goroutine الاستفادة من الجملة المقدمة لتحقق مما إذا كانت القناة مفتوحة أو مغلقة:
ele, ok := <- Mychannel
في هذا السياق، إذا كانت قيمة ok صحيحة، فإن ذلك يعني أن القناة مفتوحة، لذا يمكن تنفيذ عملية القراءة. وإذا كانت القيمة false، فإن ذلك يعني أن القناة مغلقة، لذا لن يتم تنفيذ عملية القراءة.
//شرح برنامج Go //إغلاق القناة المستخدمة //دورات range و إغلاق الدالة package main import "fmt" func myfun(mychnl chan string) { for v := 0; v < 4; v++ { mychnl <- "w3codebox" } close(mychnl) } func main() { //إنشاء قناة c := make(chan string) //استخدام Goroutine go myfun(c) //عندما تكون قيمة ok صحيحة، فإن ذلك يعني أن القناة مفتوحة، يمكن إرسال أو استقبال بيانات //عندما يتم تعيين قيمة ok إلى false، فإن ذلك يعني أن القناة مغلقة for { res, ok := <-c if ok == false { fmt.Println(قناة مغلقة، ok) قطع } fmt.Println("فتح القناة: ", res, ok) } }
الإخراج:
فتح القناة: w3codebox: نعم فتح القناة: w3codebox: نعم فتح القناة: w3codebox: نعم فتح القناة: w3codebox: نعم إغلاق القناة: لا
حظر الإرسال والاستقبال:في القنوات، عند إرسال البيانات إلى القناة، يتم حظر جملة الإرسال حتى يتم قراءة البيانات من قبل goroutine آخر، بشكل مشابه، عند استقبال البيانات من قناة، يتم حظر جملة القراءة حتى يتم إرسال البيانات من قبل goroutine أخرى.
قناة بدون قيمة: قناةالقيمة الافتراضية هي nil.
حلقة For في القناة: يمكن للحلقة for مرور القيم المرسلة عبر القناة حتى يتم إغلاقها.
النص:
for item := range Chnl { // جملة... }
package main import "fmt" func main() { // استخدم دالة make() لإنشاء قناة mychnl := make(chan string) // غوروتين مجهولة go func() { mychnl <- "GFG" mychnl <- "gfg" mychnl <- "Geeks" mychnl <- "w3codebox" close(mychnl) } // استخدام حلقة for for res := range mychnl { fmt.Println(res) } }
الإخراج:
GFG gfg Geeks w3codebox
طول القناة:في القنوات، يمكنك استخدامدالة len()إيجاد طول القناة. هنا، الطول هو عدد القيم التي تقف في منطقة التخزين للقناة.
package main import "fmt" func main() { // استخدم دالة make() لإنشاء قناة mychnl := make(chan string, 4) mychnl <- "GFG" mychnl <- "gfg" mychnl <- "Geeks" mychnl <- "w3codebox" // استخدم دالة len() للعثور على طول القناة fmt.Println("طول القناة: ", len(mychnl)) }
الإخراج:
طول القناة: 4
قدرة القناة:في القنوات، يمكنك استخدام دالة cap() لمعرفة قدرة القناة. هنا، قدرة الب缓冲 هو حجمه.
package main import "fmt" func main() { // استخدم دالة make() لإنشاء قناة mychnl := make(chan string, 4) mychnl <- "GFG" mychnl <- "gfg" mychnl <- "Geeks" mychnl <- "w3codebox" // استخدم دالة cap() للعثور على قدرة القناة fmt.Println("قدرة القناة: ", cap(mychnl)) }
الإخراج:
قدرة القناة: 5
Select و جملة case في القناة:في لغة go، جملة select تشبه جملة switch بدون أي معطيات إدخال. يمكن استخدام جملة select في القنوات لتنفيذ عملية واحدة من عدة عمليات مقدمة من مكتبات الحالات.