الكتاب الأساسي

مقدمة إلى عناصر الشيفرة المصدرية

تشتهر Go ببساطتها ونظافة صياغتها. تقدّم هذه المقالة عناصر الشيفرة المصدرية الشائعة في البرمجة من خلال مثال بسيط. سيساعد ذلك المبرمجين الجدد في Go (gophers) على تكوين فكرة أساسية عن استخدام عناصر Go.

البرمجة وعناصر الشيفرة المصدرية

يمكن النظر إلى البرمجة على أنها التلاعب بالعمليات بكل الطرق الممكنة لتحقيق أهداف معيّنة. تكتب العمليات البيانات وتقرؤها من أجهزة العتاد لإنجاز المهام. وفي الحواسيب الحديثة، العمليات الأولية هي تعليمات CPU وGPU منخفضة المستوى. وتشمل أجهزة العتاد الشائعة الذاكرة، والقرص، وبطاقة الشبكة، وبطاقة الرسوميات، والشاشة، ولوحة المفاتيح، والفأرة، وما إلى ذلك.

البرمجة عبر التلاعب بالتعليمات منخفضة المستوى مباشرةً أمرٌ مضنٍ وعُرضة للخطأ. لذلك تُغلّف لغات البرمجة عالية المستوى بعض العمليات منخفضة المستوى، وتُجرّد البيانات، لجعل البرمجة أكثر بديهية وملاءمةً للبشر.

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

تُجرَّد البيانات في معظم لغات البرمجة عالية المستوى إلى أنواع وقيم. ويمكن النظر إلى الأنواع على أنها قوالب للقيم، وإلى القيم على أنها تجسيدات للأنواع. وتدعم معظم اللغات عدة أنواع مدمجة، كما تدعم الأنواع المخصّصة. ونظام الأنواع في لغة برمجة هو روح تلك اللغة.

قد يُستخدم عدد كبير من القيم في البرمجة. ويمكن تمثيل بعضها بقيمها الحرفية (تمثيلاتها النصية) مباشرةً، لكن لا يمكن ذلك لبعضها الآخر. ولجعل البرمجة مرنة وأقل عرضة للخطأ، تُسمّى قيم كثيرة. وتشمل هذه القيم المتغيرات والثوابت المسمّاة.

تُسمّى الدوال المسمّاة والقيم المسمّاة (بما فيها المتغيرات والثوابت المسمّاة) والأنواع المعرّفة واسم النوع المستعار (type alias) عناصر الشيفرة. ويجب أن تكون أسماء عناصر الشيفرة معرّفات. ويجب أيضاً أن تكون أسماء الحزم وأسماء استيراد الحزم معرّفات.

تُترجم شيفرة البرمجة عالية المستوى إلى تعليمات CPU منخفضة المستوى بواسطة المصرّفات كي تُنفَّذ. ولمساعدة المصرّفات على تحليل شيفرة البرمجة عالية المستوى، تُحجز كلمات كثيرة لمنع استخدامها كمعرّفات. وتُسمّى هذه الكلمات كلمات مفتاحية.

تستخدم كثير من لغات البرمجة عالية المستوى الحديثة الحزم لتنظيم الشيفرة. ويجب أن تستورد حزمةٌ حزمةً أخرى لتستخدم عناصر الشيفرة المصدَّرة (العامة) في تلك الحزمة. ويجب أيضاً أن تكون أسماء الحزم وأسماء استيراد الحزم معرّفات.

رغم أن الشيفرة المكتوبة بلغات البرمجة عالية المستوى أسهل فهماً من لغات الآلة منخفضة المستوى، فإننا ما زلنا نحتاج إلى بعض التعليقات لشرح منطق بعض الشيفرة. ويحتوي البرنامج المثال في القسم التالي على تعليقات كثيرة.

برنامج Go تجريبي بسيط

لنطّلع على برنامج Go تجريبي قصير للتعرّف على جميع أنواع عناصر الشيفرة في Go. وكما في بعض اللغات الأخرى، تبدأ تعليقات السطر في Go بـ //، ويُحاط كل تعليق كتلة بزوج من /* و*/.

في ما يلي برنامج Go التجريبي. يُرجى قراءة التعليقات للاطلاع على الشروح. وتأتي شروح إضافية بعد البرنامج.


package main // تحديد حزمة الملف المصدر

import "math/rand" // استيراد حزمة قياسية

const MaxRnd = 16 // تعريف ثابت مسمّى

// تعريف دالة
/*
 StatRandomNumbers تولّد عدداً معيّناً من الأعداد
 الصحيحة العشوائية غير السالبة التي تقل عن
 MaxRnd، ثم تحصي وتُرجع عددي الأعداد الصغيرة
 والكبيرة بين الأعداد العشوائية المولَّدة.
 يحدّد n عدد الأعداد العشوائية المطلوب توليدها.
*/
func StatRandomNumbers(n int) (int, int) {
	// تعريف متغيرين (كلاهما 0).
	var a, b int
	// مسار تحكم بحلقة for.
	for i := 0; i < n; i++ {
		// مسار تحكم if-else.
		if rand.Intn(MaxRnd) < MaxRnd/2 {
			a = a + 1
		} else {
			b++ // مثل: b = b + 1
		}
	}
	return a, b // تُرجع هذه الدالة نتيجتين
}

// الدالة "main" هي دالة الدخول للبرنامج.
func main() {
	var num = 100
	// استدعاء الدالة StatRandomNumbers المعرّفة.
	x, y := StatRandomNumbers(num)
	// استدعاء دالتين مدمجتين (print و println).
	print("Result: ", x, " + ", y, " = ", num, "? ")
	println(x+y == num)
}

احفظ الشيفرة المصدرية أعلاه في ملف باسم basic-code-element-demo.go وشغّل هذا البرنامج. ستحصل على ناتج مشابه لما يلي:


$ go run basic-code-element-demo.go
Result: 46 + 54 = 100? true

في البرنامج أعلاه، تُعدّ package وimport وconst وfunc وvar وfor وif وelse وreturn كلها كلمات مفتاحية. ومعظم الكلمات الأخرى في البرنامج معرّفات. يُرجى قراءة الكلمات المفتاحية والمعرّفات لمزيد من المعلومات عن الكلمات المفتاحية والمعرّفات.

تشير كلمات int الأربع في السطرين 15 و17 إلى النوع int المدمج، وهو أحد أنواع كثيرة من الأعداد الصحيحة في Go. وتُعدّ 16 في السطر 5، و0 في السطر 19، و2 في السطر 21، و1 في السطر 22، و100 في السطر 32 بعض القيم الحرفية للأعداد الصحيحة. و"Result: " في السطر 36 قيمة حرفية نصية. يُرجى قراءة الأنواع الأساسية وقيمها الحرفية لمزيد من المعلومات عن الأنواع الأساسية المدمجة أعلاه وقيمها الحرفية. وستُقدَّم أنواع أخرى (الأنواع المركّبة) لاحقاً في مقالات أخرى.

السطر 22 إسناد. ويعرّف السطر 5 ثابتاً مسمّى هو MaxRnd. ويعرّف السطران 17 و32 ثلاثة متغيرات بصيغة تعريف المتغيرات القياسية. أما المتغير i في السطر 19 والمتغيران x وy في السطر 34 فمعرّفة بصيغة تعريف المتغيرات القصيرة. وقد حدّدنا النوع int للمتغيرين a وb. وسيستنتج مصرّف Go أن أنواع i وnum وx وy كلها int، لأنها مهيّأة بقيم حرفية للأعداد الصحيحة. يُرجى قراءة الثوابت والمتغيرات لمزيد من المعلومات عن القيم غير المُنمَّطة، واستنتاج الأنواع، وإسناد القيم، وكيفية تعريف المتغيرات والثوابت المسمّاة.

تُستخدم في البرنامج معاملات كثيرة، مثل معامل المقارنة «أصغر من» < في السطرين 19 و21، ومعامل «يساوي» == في السطر 37، ومعامل الجمع + في السطرين 22 و37. نعم، + في السطر 36 ليس معاملاً، بل محرف ضمن قيمة حرفية نصية. وتُسمّى القيم الداخلة في عملية معامل ما معامَلات به (operands). يُرجى قراءة المعاملات الشائعة لمزيد من المعلومات. وستُقدَّم معاملات أخرى في مقالات أخرى لاحقاً.

في السطرين 36 و37 تُستدعى دالتان مدمجتان هما print وprintln. وتُعرَّف دالة مخصّصة هي StatRandomNumbers من السطر 15 إلى السطر 28، وتُستدعى في السطر 34. ويستدعي السطر 21 أيضاً دالة هي Intn، وهي دالة معرّفة في الحزمة القياسية math/rand. واستدعاء الدالة عملية دالية. وتُسمّى قيم الإدخال المستخدمة في استدعاء دالة معطيات (arguments). يُرجى قراءة تعريف الدوال واستدعاؤها لمزيد من المعلومات.

(ملاحظة: لا يُنصح باستخدام الدالتين المدمجتين print وprintln في برمجة Go الرسمية. وينبغي بدلاً منهما استخدام الدالتين المقابلتين في الحزمة القياسية fmt في مشاريع Go الرسمية. وفي Go 101، تُستخدم الدالتان فقط في المقالات الأولى القليلة.)

يحدّد السطر 1 اسم حزمة الملف المصدر الحالي. ويجب تعريف دالة الدخول main في حزمة تُسمّى هي أيضاً main. ويستورد السطر 3 حزمة، هي حزمة الشيفرة القياسية math/rand. واسم استيرادها rand. وتُستدعى الدالة Intn المعرّفة في هذه الحزمة القياسية في السطر 21. يُرجى قراءة حزم الشيفرة واستيراد الحزم لمزيد من المعلومات عن كيفية تنظيم حزم الشيفرة واستيراد الحزم.

ستقدّم مقالة التعبيرات والجمل والجمل البسيطة ماهية التعبيرات والجمل. وبوجه خاص، تُدرَج فيها جميع أنواع الجمل البسيطة، وهي جمل خاصة. ويجب أن تكون بعض أجزاء جميع أنواع مسارات التحكم جملًا بسيطة، ويجب أن تكون أجزاء أخرى تعبيرات.

في جسم الدالة StatRandomNumbers يُستخدم مسارا تحكم. أحدهما مسار تحكم بحلقة for، وهو يضمّ الآخر، وهو مسار تحكم شرطي if-else. يُرجى قراءة مسارات التحكم الأساسية لمزيد من المعلومات عن جميع أنواع مسارات التحكم الأساسية. وستُقدَّم بعض مسارات التحكم الخاصة الأخرى في مقالات أخرى لاحقاً.

استُخدمت أسطر فارغة في البرنامج أعلاه لتحسين قابلية قراءة الشيفرة. ولأن هذا البرنامج غرضه تقديم عناصر الشيفرة، فإن فيه تعليقات كثيرة. وباستثناء تعليق التوثيق الخاص بالدالة StatRandomNumbers، فإن التعليقات الأخرى لأغراض العرض فقط. وينبغي أن نحاول جعل الشيفرة واضحة بذاتها وأن نستخدم التعليقات الضرورية فقط في المشاريع الرسمية.

حول فواصل الأسطر

كما في لغات أخرى كثيرة، تستخدم Go أيضاً زوجاً من الأقواس ({ و}) لتشكيل كتلة شيفرة صريحة. غير أن أسلوب كتابة الشيفرة في برمجة Go لا يمكن أن يكون اعتباطياً. فمثلاً، لا يمكن وضع كثير من الأقواس المعقوفة الافتتاحية ({) في السطر التالي. وإذا عدّلنا تعريف الدالة StatRandomNumbers في البرنامج أعلاه كما يلي، فسيفشل البرنامج في التصريف.


func StatRandomNumbers(n int) (int, int)
{ // خطأ صياغي
	var a, b int
	for i := 0; i < n; i++
	{ // خطأ صياغي
		if rand.Intn(MaxRnd) < MaxRnd/2
		{ // خطأ صياغي
			a = a + 1
		} else {
			b++
		}
	}
	return a, b
}

قد لا يحب بعض المبرمجين قيود فواصل الأسطر. لكن لهذه القيود فائدتين:

  1. تجعل تصريف الشيفرة أسرع.
  2. تجعل أساليب كتابة الشيفرة لدى مختلف مبرمجي Go متشابهة، فيسهل عليهم قراءة وفهم الشيفرة التي يكتبها غيرهم.

يمكننا معرفة المزيد عن قواعد فواصل الأسطر في مقالة لاحقة. وفي الوقت الحاضر، ينبغي أن نتجنّب وضع قوس معقوف افتتاحي في سطر جديد. وبعبارة أخرى، بشكل عام، لا ينبغي أن يكون أول محرف غير فارغ في سطر الشيفرة هو محرف القوس المعقوف الافتتاحي. (لكن تذكّر، من فضلك، أن هذه ليست قاعدة شاملة.)