وظائف متنوعة في Go

fade by clockbirds



قام فريق Mail.ru Cloud Solutions بترجمة مقالة حول الوظائف المتنوعة في Go. يشرح مؤلفه كيف تختلف الوظائف المتباينة عن الوظائف العادية وكيفية إنشائها.



ما هي الوظيفة المتغيرة



الوظيفة هي جزء من التعليمات البرمجية المصممة لأداء مهمة محددة. تمرر الدالة وسيطة واحدة أو أكثر ، وتقوم بإرجاع نتيجة واحدة أو أكثر.



الدوال المتغيرة هي نفسها الدوال العادية ، لكنها يمكن أن تأخذ عددًا لا نهائيًا أو متغيرًا من الوسائط.



func f(elem ...Type)


هذه صيغة دالة متغيرة نموذجية. ...يخبر عامل التشغيل ، المعروف أيضًا باسم مشغل الملاكمة ، Go بتخزين جميع وسيطات النوع Typeفي معلمة elem. بمعنى آخر ، يُنشئ Go متغيرًا elemبنوع []Type، أي شريحة. ويتم تخزين جميع الوسائط التي تم تمريرها إلى الوظيفة في الشريحة elem.



دعنا نرى مثالاً للدالة append().



append([]Type, args, arg2, argsN)


appendتتوقع الدالة أن تكون الوسيطة الأولى شريحة من النوع Type، متبوعة بعدد عشوائي من الوسائط. لكن كيف تضيف شريحة s2إلى شريحة s1؟



من تعريف الوظيفة ، append()يترتب على ذلك أنه لا يمكننا تمرير شريحتين إليها - هناك وسيطة من نوع Typeواحد فقط. لذلك ، نستخدم عامل unboxing ...لفك الشريحة إلى سلسلة من الوسائط. يمكن بعد ذلك تمريرها إلى الوظيفة append.



append(s1, s2...)


...تشير إلى كل من مشغل التعبئة ومشغل التفريغ. يظهر عامل التشغيل unboxing دائمًا بعد اسم المتغير.



في مثالنا، وشرائح s1و s2نفس النوع. عادة ما نعرف معلمات الدالة وعدد الوسائط التي تتطلبها. كيف acceptتعرف الوظيفة عدد المعلمات التي تم تمريرها إليها؟



إذا نظرت إلى إعلان الوظيفة append، يمكنك رؤية التعبير elems ...Type. يحزم كل الحجج ، بدءًا من الثانية ، في شريحة elems.



func append(slice []Type, elems ...Type) []Type


فقط الوسيطة الأخيرة في إعلان الوظيفة يمكن أن تكون متغيرة.



ومن ثم ، فإن الوسيطة الأولى للدالة appendهي شريحة فقط ، حيث يتم تعريفها على أنها شريحة. يتم تجميع جميع الحجج اللاحقة في وسيطة واحدة مسماة elems.



الآن دعونا نرى كيفية إنشاء الدالة المتغيرة الخاصة بك.



كيفية إنشاء دالة متغيرة



كما ذكرنا أعلاه ، فإن الدالة المتغيرة هي دالة عادية تأخذ عددًا متغيرًا من الوسائط. للقيام بذلك ، تحتاج إلى استخدام عامل تشغيل الملاكمة ...Type.



لنكتب دالة getMultiplesباستخدام وسيطة من factorالنوع الأول int(عامل الضرب) وعدد متغير من وسيطات النوع الإضافية int. سيتم تعبئتها في شريحة args.



تُستخدم makeلإنشاء شريحة فارغة ، فهي بنفس حجم الشريحة args. باستخدام حلقة for range، ضرب العناصر شريحة argsمن قبل factor. نضع النتيجة في شريحة فارغة جديدة multiples، والتي سنعود كنتيجة للدالة.



func getMultiples(factor int, args ...int) []int {
	multiples := make([]int, len(args))
	for index, val := range args {
		multiples[index] = val * factor
	}
	return multiples
}


هذه وظيفة بسيطة للغاية ، قم بتطبيقها داخل كتلة main().



func main() {
	s := []int{10, 20, 30}
	mult1 := getMultiples(2, s...)
	mult2 := getMultiples(3, 1, 2, 3, 4)
	fmt.Println(mult1)
	fmt.Println(mult2)
}




https://play.go.org/p/BgU6H9orhrn



ماذا يحدث إذا قمت ، في المثال أعلاه ، بتمرير شريحة s إلى وظيفةgetMultiplesكوسيطة ثانية؟ سيقوم المترجم بالإبلاغ عن خطأ: في الوسيطةgetMultiplesلا يمكن استخدامهs (type [] int)كنوعint. هذا لأن الشريحة لها نوع[]int, getMultiplesيتوقع من المعلماتint.



كيف يتم تمرير شريحة إلى دالة متغيرة



شريحة هي إشارة إلى مصفوفة. إذن ماذا يحدث عندما تمرر شريحة إلى دالة متغيرة باستخدام عامل التشغيل unboxing؟ هل ينشئ Go شريحة جديدة argsأم يستخدم شريحة قديمة s؟



نظرًا لعدم وجود أدوات مقارنة args == s، نحتاج إلى تغيير الشريحة args. ثم نكتشف ما إذا كانت الشريحة الأصلية قد تغيرت s.





https://play.go.org/p/fbNgVGu6JZO



في المثال أعلاه ، قمنا بتغيير الوظيفة قليلاً getMultiples. وبدلاً من إنشاء شريحة جديدة ، نقوم بتعيين نتائج الحساب لعناصر الشريحة args، مع استبدال العناصر الواردة بعناصر مضاعفة.



نتيجة لذلك ، نرى أن قيم الشريحة الأصليةsقد تغير. إذا قمت بتمرير الوسيطات إلى الدالة variadic عبر عامل التشغيل unboxing ، فإن Go يستخدم المراجع إلى مصفوفة البيانات التي تقوم على الأصل لإنشاء شريحة جديدة. احرص على عدم ارتكاب خطأ ، وإلا فإن البيانات الأصلية ستتغير نتيجة الحسابات.



حظا سعيدا!



ماذا تقرأ:



  1. اذهب ومخابئ وحدة المعالجة المركزية
  2. لماذا يجب على مطور الواجهة الخلفية تعلم لغة البرمجة Go
  3. قناة برقية لدينا حول التحول الرقمي



All Articles