مرحبا بالجميع!
اسمي ليكس وأنا المضيف لقناة
YouTube "
IT Beard ". وأنا شريك في السادسة من العمر. في الآونة الأخيرة ، كنت أرغب في تجاوز تقنيتي الأساسية (C # /. NET) ، وفهم جوهر
مفارقة Blob . قررت بحزم أن أجرب نفسي بلغة أخرى ، وذهب الاختيار عن طريق الصدفة على الذهاب.
من أجل الحصول على المعرفة بطريقة منظمة ، اشتركت في دورة من mail.ru ، يمكنك العثور عليها هنا:
https://www.coursera.org/learn/golang-webservices-1 . في الواقع ، فإن ما تعلمته من الأسبوع الأول من التدريب في هذه الدورة سيتم مناقشته بمزيد من التفصيل. دعنا نذهب!
سأبدأ بمقدمة صغيرة عن اللغة. تم تطوير
Go بالفعل في وقت المعالجات متعددة النواة (2007-2009) ، لذلك كل شيء جيد للغاية هنا مع العمل المتوازي عبر النوى. بالإضافة إلى ذلك ، تعمل اللغة بشكل رائع مع الطلبات التنافسية (المتزامنة). بشكل عام ، ابحث عن جميع أنواع خدمات الويب وأنظمة الويب المحملة. فقط ما هو مطلوب بالنسبة لي ، لأنني قمت بتطوير api على الويب (Web API) في السنوات الأخيرة.
بداية
للعمل مع اللغة ، يكفي تثبيت
حزمة برنامج "Go tools" بحجم 118 ميجابايت ، ويمكنك البدء في الترميز.
تحتوي البرامج النصية على
ملحق * .go ويتم تشغيلها بواسطة الأمر
go في سطر الأوامر (أنا ملتزم بسطر أوامر windows). يضع الأمر
gofmt جميع مسافات المسافة البادئة ويجعل الحلوى من الملف (رمز الكود خارج الصندوق). كما في شبكتي الفرعية المفضلة ، في تطبيق Go ، يبدأ تنفيذ البرنامج بالطريقة
الرئيسية .
ميزة رائعة لفتت انتباهي على الفور -
لا يمكنك وضع فاصلة منقوطة في نهاية السطر :)
Go هي لغة أخرى (إلى جانب python و c # و php و js و ts وغيرها) ، وهي ملائمة للعمل مع VSCode. يقدم
VSCode نفسه تمامًا جميع الحزم والتبعيات الضرورية عند كتابة التعليمات البرمجية. عند حفظ IDE ، يرجى تشغيل gofmt لك ويجعل الكود أكثر جمالا.
المتغيرات
كل شيء مألوف هنا: هناك العديد من الأنواع المختلفة ، وهناك قيم افتراضية. من غير المعتاد بالنسبة إلى المتبرع ، تعني الكلمة الرئيسية
var أن المتغير سوف يذهب إلى أبعد من ذلك ، ويمكن الإعلان عن نوع المتغير أو لا بالفعل بعد اسم المتغير. غير عادية.
بشكل عام ، هناك طرق عديدة لإعلان المتغيرات وتهيئتها. يمكنك حتى تعيين قيم لمتغيرات متعددة ، مفصولة بفواصل ، على نفس السطر. وبالمناسبة ، لا توجد قوالب ضمنية.
يحتوي Go أيضًا على عامل تشغيل "
: = " ، والذي يسمح لك بالإعلان عن المتغيرات الجديدة (والجديدة دائمًا فقط) والمتغيرات الجديدة على الفور. مرحبا باسكال ؛)
عرض السجل:
perem1, perem2 := 2, 3
إما ينشئ متغيرين جديدين ، أو ينشئ أحدهما ، والثاني يعين ببساطة قيمة جديدة. هذا يعني أنه إذا كان كلا المتغيرين موجودين بالفعل ، فلن يعمل هذا وسوف تحصل على خطأ ، فيقول إنهم يستخدمون المهمة المعتادة. المشغل
: = يجب إنشاء شيء :)
هناك أيضا وهمية مضحك - حرف تسطير أسفل السطر "_". هذا يعني عدم وجود متغير ، شيء من هذا القبيل :)
(في الأدوات الحادة ، كما اتضح فيما بعد ، إنه موجود أيضًا: https://docs.microsoft.com/en-us/dotnet/csharp/discards )
لحظة ممتعة مع سلاسل: العد القياسي لطول السلسلة لسلسلة
len (str) بحساب
البايتات ، وفي UTF8 يمكن للشخص أن يزن أكثر. لحساب الأحرف المسماة
الأحرف الرونية ، تحتاج إلى استخدام طريقة
utf8.RuneCountInString (str) من الحزمة "utf8". وحتى الآن - نحن لا نغير الخطوط (كما هو الحال في خطك المفضل).
الثوابت
الثوابت يمكن الإعلان عنها على دفعات. الثوابت لديها نوع مثير للاهتمام ، أو شيء -
iota . سأسميها Jopta. يسمح لك Jopta بالقيام ببعض الثوابت على أساس الآخرين ، شيء يشبه التكرار للثوابت (شيء يذكرنا
بالعائد من شبكة فرعية).
وحتى الآن ، قد لا تتم كتابة الثوابت. لمثل هذه الثوابت ، يقرر المحول البرمجي نوعها في الوقت المناسب. مريح ، ما هو بالفعل هناك.

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

إذا قمت بالوصول إلى المؤشر مباشرة ، فسيتغير الرابط. وإذا كان ذلك من خلال عامل التشغيل "
* " ، فستتغير قيمة المتغير الذي يقف خلف المؤشر (الذي يشير إليه). بشكل عام ، لم يكن الأمر واضحًا بعد ، ولكن بعد ذلك ، كما يقولون ، سيكون الأمر أكثر وضوحًا.
المصفوفات
حجم الصفيف هو جزء من نوع البيانات! لذلك ، فإن المصفوفات ذات الأبعاد المختلفة هي في الواقع أنواع مختلفة من البيانات وليست متوافقة.

ولكن ما هو مطلوب للصفائف إذا كانت جافة وغير قابلة للتغيير (لا يمكن تغييرها في وقت التشغيل). لذلك ، توصلنا إلى مثل هذه
الشرائح (شرائح) بناءً على المصفوفات.

شريحة لها
طول وقدرة . ذكرني قليلاً بنوع البيانات
nvarchar من SQL. أي يمكنك تخصيص مساحة ذاكرة (تخصيص ذاكرة) للصفائف الخاصة بك ، ولكن يمكنك وضع صفائف من أي طول هناك (حتى السعة). باختصار ، الشيء المثير للاهتمام ، تحتاج إلى التعود على ذلك. للاستخدام المريح للشرائح ، هناك كل أنواع الطرق مثل
make () و append () و len () و cap () وغيرها بالتأكيد. من شريحة واحدة (شريحة) ، يمكنك الحصول على شريحة فرعية قليلاً (شريحة شريحة). وبالمناسبة ،
يضيف الملحق () سعة الشريحة.
إذا كانت الشريحة الفرعية مساوية للشريحة ، فسوف تشير في الواقع إلى قطعة واحدة من الذاكرة. وبناءً على ذلك ، فإن تغيير القيمة في شريحة واحدة سيؤدي إلى تغيير في الشريحة الثانية. ولكن إذا تم توسيع أحدها من خلال
الملحق () ، فسيتم تخصيص جزء جديد من الذاكرة.
باختصار ، كل شيء جاد مع الذاكرة :)
الخريطة ، جدول التجزئة ، مجموعة النقابي
كل هذا واحد. الذهاب لديها جداول التجزئة لعمليات البحث الرئيسية السريعة. تهيئة على النحو التالي:

يمكنك إنشاء جداول فرعية (خريطة الخريطة) ، إلخ. (أي مستوى من التعشيش ، نوع من مثل). هناك قيمة افتراضية ترجع على مفاتيح غير موجودة. يؤخذ من نوع المفتاح (منطقي ، ثم خطأ). لمعرفة ما إذا كان المتغير قد عاد افتراضيًا ، أي أن المفتاح مفقود - استخدم المفتاح لوجود المفتاح (شيء مثير للاهتمام):

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

مع الشريحة التكرارية أكثر متعة (مشغل النطاق):

وحتى من خلال خريطة التجزئة ، يمكنك التكرار (على الرغم من أن التسلسل سيكون غالبًا مختلفًا ، لأن الخريطة ليست اتجاهية):

لنوع
سلسلة السلسلة يتكرر على الأحرف الرونية ، وليس البايتات.
وظائف
أعلن عبر الكلمة الأساسية
فونك . علاوة على ذلك ، تتم مقارنة عكس المنطق مرة أخرى بالشبكة الفرعية - تتم الإشارة إلى معلمات الإدخال أولاً ، ثم نوع القيمة المرجعة (يمكنك تسميتها فورًا).
يمكن للوظائف أن تُرجع
العديد من النتائج ، تمامًا مثل
tuples في شبكة فرعية .
تتم تهيئة القيم المسماة التي تُرجعها الدالة افتراضيًا مع القيم الافتراضية للنوع.
ومع ذلك ، يمكنك إنشاء
وظائف متغيرة لها عدد غير محدود من معلمات الإدخال من نفس النوع (مثل param في الشبكة الفرعية). وبعد ذلك يأتي نوع معين من الشريحة لإدخال الوظيفة.
وظائف قد يكون لها أسماء ، أو قد تكون بدون اسم -
مجهول . ويمكن أن يطلق عليه ، يمكن تعيينها للمتغيرات. يبدو جافا سكريبت. يمكنك حتى جعل أنواع تستند إلى وظائف! يمكن تمرير المهام كمعلمات (قراءة المندوبين من الشبكة الفرعية)
هناك حتى
إغلاق (هاه ، مخيف)! يمكنك الوصول إلى المتغيرات من الوظيفة خارجها (اقرأ ، في الوظيفة الأصل). هذه هي الفطائر.
يمكنك إعلان
التنفيذ المؤجل للوظائف . من خلال
تأجيل الكلمات الرئيسية يتم ذلك. أي يتم تنفيذ الوظائف المؤجلة في نهاية الوظيفة التي تم إعلانها فيها ، بالترتيب العكسي للإعلان عن هذه الوظائف المؤجلة. هنا. علاوة على ذلك ، تتم تهيئة وسيطات الدالات المؤجلة عند إعلان كتلة التأجيل. هذا مهم ، لا سيما إذا تم اعتبار وظيفة أخرى كوسيطة - سيتم تنفيذها في وقت أبكر مما تتوقع!
هلع! الذهاب لديه مثل هذه الوظيفة -
الذعر () . إنه مثل
رمي في ، ولكن ما هو أسوأ. هذه الوظيفة توقف تنفيذ البرنامج. ولكن يمكن معالجة هذا الذعر نفسه بالتأجيل ، حيث يتم تنفيذه بأي شكل من الأشكال في نهاية الوظيفة ، حتى بعد الذعر. وحتى الآن - الذعر ، وهذا ليس محاولة للقبض. هذا أسوأ!
الهياكل (الأجسام القريبة)
يُقال إن Go ليست لغة نموذجية OOP. ولكن هناك أشياء مثل
الهياكل . إذا كنت من عالم الشبكات الفرعية ، فأنت تعلم أن لدينا أيضًا هياكل - هذه تعيينات للكائنات التي يمكن تخزينها على المكدس (أنواع القيم). في Go ، تعتبر البنية نوعًا من الطريقة الوحيدة لعمل شيء ما مثل كائن. لا يمكنني التحدث عن أنواع القيمة حتى الآن ، ولكن طبيعة التفاعل مع الهياكل تشبه إلى حد كبير تلك المفصلة.
كل بنية هي نوع منفصل بشكل أساسي ويمكن أن تحتوي على مجموعة من خصائص أنواع محددة (بما في ذلك نوع بنية أخرى أو نوع وظيفة):

بالإضافة إلى ذلك ، يتم رؤية آلية معينة لوراثة الكائن المباشر من الشبكة الفرعية هنا. في الصورة أعلاه ، تتداخل بنية
الحساب مع بنية
الشخص . هذا يعني أن جميع الحقول من
الشخص ستكون متاحة في متغير من نوع
الحساب . إذا تزامنت أسماء الممتلكات (في المثال أعلاه
معرف ، اسم ) ، لن يكون هناك تعارض ، ولكن سيتم اتخاذ قيمة حقل أعلى:

طرق
نعم ، ليس فقط تشابه الأشياء ، ولكن أيضًا الطرق. تقريبا OOP :) الأسلوب عبارة عن
دالة مرتبطة بنوع معين (على سبيل المثال ، إلى بنية). تختلف الطريقة عن وظيفة ما في الإعلان: بعد الكلمة الأساسية
func ، بين قوسين ، تحتاج إلى تحديد النوع الذي تنتمي إليه هذه الطريقة ودورها في تمرير متغير من هذا النوع. ما هو الدور؟ إذا وضعت علامة النجمة أمام الكتابة ، فسيتم تمرير المتغير حسب المرجع (تذكر المؤشرات ، كان هناك أيضًا) ، ونتيجة لذلك ، داخل الطريقة التي سنعمل بها مع نوع محدد ، وليس نسخته.

من الصورة أعلاه ، يمكننا أن نستنتج أن
UpdateName لا معنى له ، لأنه يغير نسخة الهيكل وليس الأصل. وهذه النسخة لا يعود. بينما سيتغير
SetName الهيكل الأصلي (بفضل العلامة النجمية ويمر حسب المرجع).
يتم توريث الأساليب في الهياكل (ووفقًا لقواعد ميراث الممتلكات) ، أي الهيكل الأصل لديه حق الوصول إلى جميع الأساليب المتداخلة في بنيته.
أنواع أخرى يمكن أن يكون لها طرق ، وليس فقط الهياكل. قد يبدو هذا أساليب تمديد من الشبكة الفرعية ، ولكن لا. لا يمكن إنشاء الأساليب في Go إلا للأنواع المحلية ، أي الأنواع التي تم الإعلان عنها في هذه الحزمة (حول الحزم أكثر قليلاً).
الحزم ، النطاق ، مساحات الأسماء
الآن فقط أدركت أن Go ليس لديها NEIMSPACE! على الإطلاق! أدركت هذا عندما حدث خطأ بعد الترجمة ، يقولون في مجلد واحد لدي ملفين مع الطريقة الرئيسية. اتضح أنه في مرحلة التجميع ، يبدو أن كل شيء بدءًا من الأب يتم لصقه معًا في قماش واحد! المجلد في الواقع هو مساحة الاسم. هذا السحر ، أيها الرفاق :)
هنا ، بالمناسبة ، هو ما يقوله قفص الاتهام:

ملاحظة لنفسك:
تدخين قفص الاتهاموإليك مقالة صغيرة أخرى في الموضوع:
https://www.callicoder.com/golang-packages/#the-main-package-and-main-functionهكذا يقولون ، هيكل المجلد الأساسي يشبه:

بن - الثنائيات المترجمة
pkg - ملفات الكائنات المؤقتة
src - المصادر
تشير الحزم إلى اسم المجلد الذي توجد به ملفات الحزمة. نعم ، يمكن أن تحتوي الحزمة على العديد من الملفات التي يتم استيرادها إلى بعضها البعض.
هناك قاعدة أخرى مثيرة للاهتمام: يمكن استخدام الدالات والخصائص والمتغيرات والثوابت التي تبدأ بحرف كبير
خارج الحزمة ، أي
يتم استيرادها . يتم استخدام كل شيء بحرف صغير فقط داخل الحزمة. تناظرية
من المعدلات الوصول من الشبكة الفرعية.
تعمل كلمة
الاستيراد الرئيسية داخل ملف ، وليس حزمة.
واجهات
واجهات هنا مثيرة للاهتمام. نحن لسنا بحاجة إلى وراثة واجهات من هياكلنا. يكفي أن البنية ، التي تأتي كمعلمة إدخال لطريقة معينة تأخذ نوع واجهة ، تنفذ أساليب هذه الواجهة. وليس هناك مشاكل. أي أساليب واجهة لا تحتاج بالضرورة أن تنفذ من قبل الهيكل. لكن يجب أن تحتوي البنية على تنفيذ جميع الطرق المطلوبة في وظيفة معينة ، حيث يتم استخدام نوع الواجهة كمعلمة إدخال.
اتضح ، على النقيض من ، في Go ، أن الواجهة هي سمة من سمات الوظيفة التي تُستخدم فيها ، وليست خاصية لبنية محددة (كائن).
إذا كان الأمر أكثر بساطة ، فالمنطق هو هذا: لن تحتاج إلى أن تكون قادرًا على أن تكون بطيئًا. إذا كنت تعرف كيفية الدجال ، فمن المرجح أنك بطة :)
وبالمناسبة ، إذا كان هيكلك يطبق جميع أساليب بعض الواجهة ،
فيمكن تعيين هذه البنية
كقيم لمتغير الواجهة المنفذة . شيء من هذا القبيل :)
اكتب حالة التبديل
يحتوي Go على علبة تبديل خاصة يمكنها العمل وفقًا للنوع الوارد. شيء رائع:

بالمناسبة ، هذه هي الطريقة التي يمكنك بها
تحويل نوع إلى آخر (على سبيل المثال ، نوع واجهة إلى نوع بنية للحصول على حقول بنية لا يمكن الوصول إليها من الواجهة):
حسنًا - علامة منطقية على أن التحويل كان ناجحًا. لقد واجهنا بالفعل علامات :)
الواجهة الفارغة هي الوحش في عالم Go. يمكن أن يستغرق أي نوع على الإطلاق. شيء مثل
ديناميكي أو
كائن في. على سبيل المثال ، يتم استخدامه في
fmt.Println () والوظائف المماثلة التي تستخدم واجهة فارغة في التطبيق.
يمكن دمج الواجهات في بعضها البعض ، وبالتالي جعل تكوين الواجهات (ما يقال في الحرف
الأول (فصل الواجهة) لمبادئ
SOLID )
اختبارات
في Go ، تبدأ جميع وظائف الاختبار بالكلمة
Test ،
ويتم قبول إدخال اختبار وحدة
الاختبار . تتم تسمية الملفات حسب اسم ملف الاختبار + word _test (
main_test.go - اختبارات لملف
main.go ). وعلاوة على ذلك ، كل من الاختبارات وملفات الاختبار في حزمة واحدة!

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