المتغيرات مفهوم مهم في البرمجة يجب إتقانه. هي رموز تمثل قيمة تستخدم في برنامجك.
سيغطي هذا الدرس بعض الأساسيات المتعلقة بالمتغيرات وأفضل الممارسات لاستخدامها داخل برامج Go التي تقوم بإنشائها.
فهم المتغيرات
من الناحية الفنية، المتغير هو تعيين موقع تخزين لقيمة مرتبطة باسم رمزي أو معرف. نستخدم اسم المتغير للإشارة إلى تلك القيمة المخزنة داخل برنامج الكمبيوتر.
يمكننا التفكير في المتغير كتصنيف له اسم عليه، والذي تربطه بقيمة.
لنقل أن لدينا عدد صحيح، 1032049348
، ونريد تخزينه في متغير بدلاً من إعادة كتابة الرقم الطويل مراراً وتكراراً. لتحقيق ذلك، يمكننا استخدام اسم سهل التذكر، مثل المتغير i
. لتخزين قيمة في متغير، نستخدم الصيغة التالية:
يمكننا التفكير في هذا المتغير كتصنيف مرتبط بالقيمة.
التصنيف يحمل اسم المتغير i
، ويرتبط بالقيمة الصحيحة 1032049348
.
العبارة i := 1032049348
هي عبارة تعريف وتخصيص تتكون من عدة أجزاء:
- اسم المتغير (
i
) - تخصيص التصنيف القصير (
:=
) - القيمة المعلومة باسم معلومات الشركة (
1032049348
) - النواتج من نوع الداتا في Go (
int
)
سيتمناهم أن نرى لاحقا كيفية إختر نوع المعلومة بشكل مخصص في سECTION آخرة.
مع ذلك، تم إنشاء هذا المعلومة باسم معلومات مثل i
يساوي القيمة من نوع 整数 1032049348
.
بالتوفيق بين هذا القيمة والقيمة المعلومة معلومات مثل i
يساوي القيمة من نوع 整数 1032049348
.بالمزيد من المعلومات عن كيفية إستخدام المعلومات بشكل مخصص في المستقبلة، سيظهر لنا في السECTION التالية.
بالمزيد من المعلومات عن كيفية إستخدام المعلومات بشكل مخصص في المستقبلة، سيظهر لنا في السECTION التالية.
Output1032049348
لكننا سيتم إنشاء هذا المعلومة باسم معلومات مثل i
يساوي القيمة من نوع 整数 1032049348
.
Output1032048535
بالمزيد من المعلومات عن كيفية إستخدام المعلومات بشكل مخصص في المستقبلة، سيظهر لنا في السECTION التالية.
بالمزيد من المعلومات عن كيفية إستخدام المعلومات بشكل مخصص في المستقبلة، سيظهر لنا في السECTION التالية.
بالمزيد من المعلومات عن كيفية إستخدام المعلومات بشكل مخصص في المستقبلة، سيظهر لنا في السECTION التالية.
لكننا سيتم إنشاء هذا المعلومة باسم معلومات مثل x
:
Output221
تعادل القيمة التي أعادتها Go هي 221
لأن المتغير x
تم تعيينه ليساوي مجموع 76
و 145
.
يمكن للمتغيرات تمثيل أي نوع بيانات، ليس فقط الأعداد الصحيحة:
إذا طبعت أي من هذه المتغيرات، ستعيد Go ما يعادل ذلك المتغير. لنعمل مع تعيين العبارة لنوع بيانات السلسلة slice
:
Output[one two three]
لقد قمنا بتعيين قيمة الشريحة []string{"one", "two", "three"}
إلى المتغير slice
، ثم استخدمنا دالة fmt.Println
لطباعة هذه القيمة عن طريق استدعاء slice
.
يعمل المتغيرات عن طريق تخصيص مساحة صغيرة في ذاكرة الكمبيوتر الخاص بك تقبل القيم المحددة التي يتم تخصيصها لتلك المساحة.
تعريف المتغيرات
في Go، هناك عدة طرق لتعريف متغير، وفي بعض الحالات، أكثر من طريقة لتعريف نفس المتغير والقيمة بالضبط.
يمكننا تعريف متغير يسمى i
من نوع بيانات int
دون تهيئة. هذا يعني أننا سنعرف مساحة لوضع قيمة، لكننا لن نعطيها قيمة أولية:
هذا ينشئ متغيرًا تم تعريفه كـ i
من نوع بيانات int
.
يمكننا تهيئة القيمة باستخدام المشغل (=) كما في المثال التالي:
في لغة Go، كلا هذين الأشكال من الإعلانات تُسمى إعلانات متقدمة للمتغيرات.
يمكننا أيضًا استخدام إعلان مختصر للمتغير:
في هذه الحالة، لدينا متغير يُدعى i
، ونوع بيانات int
. عندما لا نحدد نوع بيانات، سيقوم Go بتحديد نوع البيانات.
مع الطريقة الثلاثة لإعلان المتغيرات، اتبعت مجتمع Go التالي الأمثلة:
-
استخدم الشكل الطويل فقط،
var i int
، عندما لا تقوم بتهيئة المتغير. -
استخدم الشكل القصير،
i := 1
، عند الإعلان والتهيئة. -
إذا لم تكن ترغب في تحديد Go لنوع بياناتك، ومع ذلك ترغب في استخدام إعلان مختصر للمتغير، يمكنك ضم القيمة في النوع المرغوب فيه بالسياق التالي:
لا يُعتبر استخدام شكل إعلان متقدم للمتغيرات إذا كنا نقوم بتهيئة القيمة هو شيء امثلي في Go:
من الجيد أن نتبع الطريقة التي تُتبعها مجتمع Go عادةً في إعلان المتغيرات حتى يتمكن الآخرون من قراءة برامجك بسلاسة.
القيم الصفرية
جميع الأنواع المدمجة لها قيمة صفرية. أي متغير مخصص قابل للاستخدام حتى لو لم يتم تعيين قيمة له أبداً. يمكننا رؤية القيم الصفرية للأنواع التالية:
Outputvar a int = 0
var b string = ""
var c float64 = 0
var d bool = false
استخدمنا الفعل %T
في عبارة fmt.Printf
. هذا يخبر الدالة بطباعة نوع البيانات
للمتغير.
في Go، لأن جميع القيم لها قيمة صفرية
، لا يمكننا الحصول على قيم غير معرفة
مثل بعض اللغات الأخرى. على سبيل المثال، منطقي
في بعض اللغات يمكن أن يكون غير معرف
، صحيح
، أو خطأ
، مما يسمح بـ ثلاث
حالات للمتغير. في Go، لا يمكننا الحصول على أكثر من حالتين
لقيمة منطقية.
تسمية المتغيرات: القواعد والأسلوب
تسمية المتغيرات مرنة للغاية، ولكن هناك بعض القواعد التي يجب مراعاتها:
- يجب أن تكون أسماء المتغيرات كلمة واحدة فقط (أي بدون مسافات).
- يجب أن تتكون أسماء المتغيرات من حروف وأرقام وشرطات سفلية (
_
) فقط. - لا يمكن أن تبدأ أسماء المتغيرات برقم.
اتبعًا هذه القواعد، دعونا ننظر إلى أسماء متغيرات صالحة وغير صالحة:
Valid | Invalid | Why Invalid |
---|---|---|
userName |
user-name |
Hyphens are not permitted |
name4 |
4name |
Cannot begin with a number |
user |
$user |
Cannot use symbols |
userName |
user name |
Cannot be more than one word |
ومن المهم أيضًا أن تتذكر، عند تسمية المتغيرات، أنها حساسة بالحالة. هذه الأسماء userName
، USERNAME
، UserName
، وuSERnAME
هي جميعها متغيرات مختلفة تمامًا. من أفضل الممارسات تجنب استخدام أسماء متغيرات متشابهة ضمن برنامج لضمان أنك ومساهميك الحاليين والمستقبليين تتمكنون من تتبع متغيراتك.
بينما تكون المتغيرات حساسة بالحالة، فإن حالة الحرف الأول لمتغير لها معنى خاص في لغة Go. إذا بدأت المتغيرة بحرف أولي كبير، فإن تلك المتغيرة قابلة للوصول من خارج الحزمة التي تم إعلانها فيها (أو exported
). إذا بدأت المتغيرة بحرف صغير، فإنها متاحة فقط داخل الحزمة التي تم إعلانها فيها.
Email
تبدأ بحرف أولي كبير ويمكن الوصول إليها من قبل الحزمات الأخرى. password
تبدأ بحرف صغير، ويمكن الوصول إليها فقط داخل الحزمة التي تم إعلانها فيها.
من العادة في Go استخدام أسماء متغيرات قصيرة جدًا. من بين الخيارين استخدام userName
وuser
لمتغير، فإن الاختيار الأدبي سيكون user
.
يلعب النطاق أيضًا دورًا في قصارة اسم المتغير. القاعدة هي أن كلما كان نطاق المتغير أصغر، كان اسم المتغير أصغر:
نستخدم المتغير `names
` في نطاق أكبر، لذا من الشائع إعطاؤه اسمًا أكثر معنى للمساعدة في تذكر ما يعنيه في البرنامج. ومع ذلك، نستخدم المتغيرات `i
` و `n
` فورًا في السطر التالي من الكود، ثم لا نستخدمها مرة أخرى… وبسبب ذلك، لن يخلط ذلك شخصًا يقرأ الكود حول مكان استخدام المتغيرات، أو ما تعنيه.
التالي، دعونا نغطي بعض الملاحظات حول نمط المتغير. النمط هو استخدام `MixedCaps
` أو `mixedCaps
` بدلاً من الشرطات السفلية للأسماء متعددة الكلمات.
Conventional Style | Unconventional Style | Why Unconventional |
---|---|---|
userName |
user_name |
Underscores are not conventional |
i |
index |
prefer i over index as it is shorter |
serveHTTP |
serveHttp |
acronyms should be capitalized |
الأهم من ذلك هو أن تكون متسقًا، وأن يتفق الفريق الذي تعمل معه على النمط.
إعادة تعيين المتغيرات
كما يوحي الكلمة “متغير”، يمكننا تغيير متغيرات Go بسهولة. هذا يعني أنه يمكننا ربط قيمة مختلفة بمتغير تم تعيينه سابقًا من خلال إعادة التعيين. أن تكون قادرًا على إعادة التعيين مفيد لأنه طوال مسار البرنامج قد نحتاج إلى قبول قيم جيدة التوليد في متغيرات تم تهيئتها بالفعل. قد نحتاج أيضًا إلى تغيير التعيين إلى شيء تم تعريفه مسبقًا.
معرفة أنه يمكننا إعادة تعيين متغير بسهولة يمكن أن يكون مفيدًا عند العمل على برنامج كبير كتبه شخص آخر، ولا يتضح ما هي المتغيرات التي تم تعريفها بالفعل.
لنُعَرِّف قيمة 76
لمتغير يُسمى i
من نوع int
، ثم نُعَدِّله ليصبح قيمته 42
:
Output76
42
يوضح هذا المثال أنه يمكننا تعيين المتغير i
بقيمة عدد صحيح أولاً، ثم إعادة تعيين المتغير i
هذه المرة بقيمة 42
.
ملاحظة: عندما تعلن و تهيئة متغير، يمكنك استخدام :=
، ولكن عندما تريد فقط تغيير قيمة متغير معلن بالفعل، فأنت تحتاج فقط إلى استخدام عامل التساوي (=
).
نظرًا لأن Go هي لغة مُصنَّفة (typed
)، لا يمكننا تعيين نوع إلى آخر. على سبيل المثال، لا يمكننا تعيين القيمة "Sammy"
إلى متغير من نوع int
:
محاولة تعيين أنواع مختلفة لبعضها البعض ستؤدي إلى خطأ في وقت التحويل (compile-time error
):
Outputcannot use "Sammy" (type string) as type int in assignment
لن تسمح لنا Go باستخدام اسم متغير أكثر من مرة:
Outputs redeclared in this block
إذا حاولنا استخدام تعريف المتغير المختصر أكثر من مرة لنفس اسم المتغير، سنتلقى أيضًا خطأ تحويل. قد يحدث هذا عن طريق الخطأ، لذا فهم ما تعنيه رسالة الخطأ مفيد:
Outputno new variables on left side of :=
وبالمثل، تمامًا مثل تعريف المتغير، سيحسن اختيار أسماء متغيراتك قابلية قراءة برنامجك بالنسبة لك، وللآخرين، عندما تعود إليه في المستقبل.
التعيين المتعدد
يسمح لنا Go أيضًا بتعيين عدة قيم لعدة متغيرات في نفس السطر. يمكن أن تكون كل هذه القيم من نوع بيانات مختلف:
Outputshark
2.05
15
في هذا المثال، تم تعيين المتغير j
إلى السلسلة "shark"
، وتم تعيين المتغير k
إلى العدد العشري 2.05
، وتم تعيين المتغير l
إلى العدد الصحيح 15
.
هذا النهج في تعيين متغيرات متعددة لقيم متعددة في سطر واحد يمكن أن يقلل من عدد الأسطر في الكود الخاص بك. ومع ذلك، من المهم ألا تهدر القابلية للقراءة من أجل عدد أقل من الأسطر من الكود.
المتغيرات العامة والمحلية
عند استخدام المتغيرات داخل برنامج، من المهم أن نأخذ نطاق المتغير في الاعتبار. يشير نطاق المتغير إلى الأماكن المعينة التي يمكن الوصول إليها منها داخل كود برنامج معين. هذا يعني أنه لا يمكن الوصول إلى جميع المتغيرات من جميع أنحاء برنامج معين – بعض المتغيرات سيكون عامة وبعضها سيكون محليًا.
توجد المتغيرات العامة خارج الدوال. توجد المتغيرات المحلية داخل الدوال.
دعونا نلقي نظرة على المتغيرات العامة والمحلية في العمل:
Outputlocal
global
نستخدم var g = "global"
هنا لإنشاء متغير عالمي خارج المétodo. ومن ثم نحن نحدد المétodo printLocal()
. داخل المétodo تم تعيين متغير محلي يدعى l
ومن ثم نسرده. يتنتهي البرنامج بهذه المدعومة printLocal()
ومن ثم نسرد المتغير العالمي g
.
لأن g
متغير عالمي يمكننا أن نشير إليه في printLocal()
. دعونا نغير البرنامج السابق للقيام بذلك:
Outputlocal
global
global
نبدأ بالتعيين لمتغير عالمي g
, var g = "global"
. في المétodo main
نطلب المétodo printLocal
, الذي يدعوم متغير محلي l
ونسرده, fmt.Println(l)
. ثم ينسرد printLocal
المتغير العالمي g
, fmt.Println(g)
. 即使 g
لم يتم تعيينه في printLocal
, يمكن الوصول إليه لأنه تم تعيينه في نطاق عالمي. وأخيرًا ينسرد المétodo main
g
أيضًا.
الآن دعونا نحاول إنجاز متغير محلي خارج المétodo:
Outputundefined: l
لا يمكننا استخدام متغير محلي خارج المétodo الذي يمكن تعيينه فيه. إذا حاولت فعل ذلك سوف تحصل على خطأ undefined
عند التجهيز.
دعونا ننظر إلى مثال آخر حيث نستخدم نفس الاسم لمتغير عالمي ومتغير محلي:
Output10
7
5
في هذا البرنامج، قمنا بتعريف المتغير `num1
` مرتين. أولاً، قمنا بتعريف `num1
` على المستوى العام، `var num1 = 5
`، ومرة أخرى ضمن النطاق المحلي للدالة `printNumbers
`، `num1 := 10
`. عندما نطبع `num1
` من برنامج `main
`، نرى القيمة `5` مطبوعة. وذلك لأن `main
` يرى فقط تعريف المتغير العام. ومع ذلك، عندما نطبع `num1
` من دالة `printNumbers
`، فإنها ترى التعريف المحلي، وستطبع القيمة `10`. على الرغم من أن `printNumbers
` تنشئ متغيرًا جديدًا يسمى `num1
` وتعينه القيمة `10`، إلا أن ذلك لا يؤثر على المثيل العام لـ `num1
` بالقيمة `5`.
عند العمل مع المتغيرات، تحتاج أيضًا إلى النظر في أي أجزاء من برنامجك ستحتاج إلى الوصول إلى كل متغير؛ واختيار متغير عام أو محلي وفقًا لذلك. في برامج Go، ستجد أن المتغيرات المحلية عادةً ما تكون أكثر شيوعًا.
الثوابت
الثوابت مثل المتغيرات، باستثناء أنها لا يمكن تعديلها بمجرد تعريفها. الثوابت مفيدة لتحديد قيمة سيتم استخدامها أكثر من مرة في برنامجك، ولكن لا ينبغي أن تتغير.
مثلاً، إذا كنا نريد إعلان معدل الضريبة لنظام عربة التسوق، يمكننا استخدام مستمر ومن ثم حساب الضريبة في أجزاء مختلفة من البرنامج الخاص بنا. في مرحلة ما في المستقبل، إذا تغير معدل الضريبة، سنحتاج فقط إلى تغيير ذلك القيمة في مكان واحد في البرنامج الخاص بنا. إذا استخدمنا متغيرًا، فمن الممكن أن نغير بصادفة القيمة في مكان ما في البرنامج الخاص بنا، مما قد يؤدي إلى حساب غير صحيح.
لإعلان مستمر، يمكننا استخدام الصيغة التالية:
OutputSammy
إذا حاولنا تعديل مستمر بعد تعليمته، سنحصل على خطأ في وقت التركيب:
Outputcannot assign to shark
المستمرات يمكن أن تكون غير مصفوفة
. هذا يمكن أن يكون مفيدًا عند العمل مع أرقام مثل بيانات النوع الصحيح. إذا كان المستمر غير مصفوف
، فإنه يتم تحويله بوضوح، بينما المستمرات المصفوفة لا. دعونا نرى كيف يمكننا استخدام المستمرات:
Output8760
21900
21960
إذا قمت بإعلان مستمر بنوع، فسيكون ذلك النوع المحدد بالضبط. هنا عندما نعلن المستمر leapYear
، نحدده كنوع بيانات int32
. لذلك، هو مستمر مصفوف
، مما يعني أنه يمكنه التشغيل فقط مع أنواع بيانات int32
. المستمر year
الذي نعلنه بدون نوع، لذلك يعتبر غير مصفوف
. وبسبب هذا، يمكنك استخدامه مع أي نوع بيانات صحيح.
عندما تم تعريف hours
، تم تصديق أنها من نوع int
لأننا لم نعطيها نوعًا بوضوح، hours := 24
. عندما علنا minutes
، قمنا بتعريفها بوضوح كـ int32
، minutes := int32(60)
.
الآن دعونا نتحدث عن كل حساب ولماذا يعمل:
في هذه الحالة، hours
هو int
، وyears
هو غير محدد النوع. عندما يتم ترجمة البرنامج، يتم تحويل years
صراحة إلى int
، مما يسمح بنجاح عملية الضرب.
في هذه الحالة، minutes
هو int32
، وyear
هو غير محدد النوع. عندما يتم ترجمة البرنامج، يتم تحويل years
صراحة إلى int32
، مما يسمح بنجاح عملية الضرب.
في هذه الحالة، minutes
هو int32
، وleapYear
هو ثابت محدد النوع من int32
. لا يوجد شيء يجب على المترجم القيام به هذه المرة لأن كلا المتغيرين من نفس النوع بالفعل.
إذا حاولنا ضرب نوعين ليسا محددين النوع
ولا يتوافقان، لن يتم ترجمة البرنامج:
Outputinvalid operation: hours * leapYear (mismatched types int and int32)
في هذه الحالة، تم استنتاج hours
كint
، وتم الإعلان عن leapYear
بشكل صريح كint32
. نظرًا لأن Go هي لغة محددة النوع، فإن int
وint32
ليسا متوافقين للعمليات الرياضية. لضربهما، ستحتاج لتحويل أحدهما إلى int32
أو int
.
الخاتمة
في هذا الدرس راجعنا بعض الحالات الاستخدامية الشائعة للمتغيرات داخل Go. المتغيرات هي عنصر بناء مهم في البرمجة، حيث تعمل كرموز تمثل قيمةً لنوع البيانات الذي نستخدمه في برنامج.
Source:
https://www.digitalocean.com/community/tutorials/how-to-use-variables-and-constants-in-go