جلبت Go1.23 ميزة النطاق الزائد عن الوظيفة التي كانت بمثابة تجربة في go1.22 لاستخدامها بشكل حقيقي. إذا كان أي شخص قد قرأ نموذج التعليمات البرمجية، فقد يتعين عليك ذلك التأمل لفترة طويلة لا تفعل ذلك. سوف يشرح لك P'Yod بطريقة بسيطة جدًا لتقرأها
بدءًا من مواصفات العبارات ذات جملة النطاق، تمت إضافة 3 أنواع من التعبيرات:
func(func() bool) func(func(V) bool) func(func(K, V) bool)
أود إضافة متغير واحد للتوضيح كما يلي
f func(yield func() bool) f func(yield func(V) bool) f func(yield func(K, V) bool)
تقول المواصفات أنه عندما نستخدم الدالة f كتعبير في الغضب، في كل مرة نستدعي فيها دالة العائد هناك قبل إنهاء الدالة f، نحصل على النتيجة في كل حلقة. مساوية للقيمة التي أدخلناها في العائد، ما زلت في حيرة من أمري عندما أشرح ذلك. كتابة كود أفضل
func main() { for range loop { fmt.Println("-") } } func loop(yield func() bool) { yield() yield() }
الإخراج:
- -
إذا كتبنا كودًا مثل هذا، فسنحصل على حلقتين كاملتين لأننا نسمي العائد 2 مرات في f وفقًا للمواصفات، وهنا نسميها حلقة ولن تعيد إلينا أي شيء. لأننا نختار استخدام نمط ذو عائد لا يقبل أي وسيطات
مثال آخر
func main() { for i := range loop { fmt.Println(i) } } func loop(yield func(int) bool) { yield(3) yield(7) }
الإخراج:
3 7
بهذه الطريقة سنحصل على جولتين أيضًا لأننا نسمي العائد مرة واحدة وسيعيد النطاق الآن قيمتين هما 3 و 7 والتي نستخدمها لاستدعاء العائد في كل مرة
مثال آخر
func main() { for i := range loop { fmt.Println(i) } } func Loop(yield func(int, string) bool) { yield(3, "three") yield(5, "five") yield(7, "seven") }
الإخراج:
3 three 5 five 7 seven
سنحصل على 3 حلقات ونحصل على قيمتين لكل حلقة وفقًا لما نضعه في العائد في كل مرة
ويمكننا أيضًا استدعاء العائد عن طريق إدراج أي نوع من الوسائط مثل
func loop(yield func(string, bool) bool) { yield("three", true) yield("five", false) yield("seven", false) }
الآن بعد أن فهمنا آلية ذلك. عندما نقرأ الأمثلة الصعبة سنفهم المزيد، مثل المثال الموجود في Go Wiki: Rangefunc Experiment
package slices func Backward[E any](s []E) func(func(int, E) bool) { return func(yield func(int, E) bool) { for i := len(s)-1; i >= 0; i-- { if !yield(i, s[i]) { return } } } }
رئيسي
s := []string{"hello", "world"} for i, x := range slices.Backward(s) { fmt.Println(i, x) }
أسهل بكثير في القراءة، أليس كذلك؟ وفي النهاية، كيفية تطبيقه متروك لك. نحن ننظر فقط إلى عدد المرات التي يتم فيها استدعاء العائد. لن تحصل عليه إلا عندما تضعه في النطاق
القيمة التي ستخرج هي القيمة التي تم إسقاطها في العائد.
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3