"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > خطوات الطفل مع الذهاب

خطوات الطفل مع الذهاب

تم النشر بتاريخ 2024-08-23
تصفح:268

Baby steps with Go

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

هذه ليست جولة إرشادية، ويمكن القول إنها ليست مكتوبة لأي شخص آخر غيري، كتذكير شخصي.

لقد قدمت لنفسي مشروعًا صغيرًا يسمى Os-Release-Q. كنت أعتزم أن أكون قادرًا على الحصول على ملف ثنائي في أي نظام أديره، بحيث أتمكن من طباعة المعلومات التي أحتاجها بالضبط، دون الحاجة إلى تحليلها أو فحصها.

العقبة الأولى: الاستيراد

يتحدث البحث في الويب كثيرًا عن استيراد حزم الأشخاص الآخرين، ولكن القليل جدًا عن تنظيم التعليمات البرمجية الخاصة بالفرد. حتى المستندات تركز على go get بدلاً من فصل الاهتمامات.

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

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

  • يحتاج المستوى الأعلى إلى go.mod للإعلان عن اسم الوحدة النمطية
  • يمكنني بعد ذلك تعيين دليل src/ في المستوى الأعلى، وsrc/main.go لوضع وظيفتي الرئيسية، مع إعلان الحزمة الرئيسية في الأعلى
  • يعد وضع التعليمات البرمجية في ملفات أخرى أمرًا بسيطًا مثل إنشاء ملف مثل src/others.go مع الإعلان الرئيسي للحزمة.
  • تصبح جميع الوظائف والمتغيرات متاحة مباشرة في أي ملف آخر من ملفات الحزمة الرئيسية، ولكن يجب ذكر الملفات بشكل صريح أثناء إنشاء استدعاء FILES

بالنسبة للوحدات الفرعية المحلية، يجب أن تكون الوحدة الفرعية موجودة في مجلد. يمكنه الإعلان عن اسم الوحدة الفرعية للحزمة .

لنفترض أنه موجود في src/submod/، مع المنفذ الرئيسي في src/submod/submod.go. في main.go نقوم باستيراد "module-name/src/submod" (مع سحب اسم الوحدة من go.mod). ومن ثم يمكننا استدعاء submod.SomeFunction().

نلاحظ أن وظائف الوحدة الفرعية متاحة فقط للمستوردين إذا كانت أسمائهم تبدأ بحرف كبير. لذلك لا داعي لاستخدام submod.myFunction() - يجب أن يكون submod.MyFunction().

هناك بالتأكيد اعتبارات أخرى حول الوحدات الفرعية والواردات، ولكن فيما يتعلق بالحفاظ على التعليمات البرمجية منظمة ومنفصلة، ​​فهذه هي الأساسيات.

للحفاظ على الأمور منطقية، حاولت أن يكون لدي ملف واحد فقط يعلن عن الحزمة الرئيسية، وعزل الباقي إلى وحدات فرعية - يتم استيرادها تلقائيًا دون الحاجة إلى الإعلان عنها في قائمة ملفات go build FILES.

القيام بالمهام الأساسية

بعد أن قمت بحل هذه المشكلة الخاصة بـ Go، تم وضع الباقي في مكانه بسهولة تامة. لكل مهمة أساسية كان هناك بالطبع إدخال StackOverflow، أو صفحة GoByExample.com، وبشكل أساسي، مرجع لغة Go.

  • تتم معالجة السلسلة عبر حزمة السلاسل
  • تحتوي معالجة المصفوفة على عدد من الوظائف الأصلية، منها نمط base_array = append(base_array, item1, item2) - وهو يعمل أيضًا على توسيع مصفوفة بقيم أخرى عبر append(base,other_array...)
  • تتم معالجة الأخطاء عن طريق تمرير كائنات الخطأ عادةً، ولكن ليس بالضرورة.
  • يوجد lib "سجل" لسجل مفيد تم تكوينه مسبقًا لمنع التلاعب. يتضمن استدعاء log.Fatal(message) الذي يسجل خطأ، بالإضافة إلى الخروج فورًا.
  • استدعاء العمليات الفرعية أمر سهل عبر مكتبة "os/exec"، باستخدام نمط exec.Command(base, args...)

هناك مهمتان شائعتان بشكل خاص تستحقان فقرات خاصة بهما.

معالجة الأخطاء

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

// explicit return item `err` forces us to be aware of it
// but having the ability to check it in the same breath is not so bad
if result, err := someCall(); err != nil {
    log.Fatal("Sorry.")
}

// Equally valid is
/*
result, err := someCall()
if err != nil {
    log.Fatal("Sorry")
}
*/

fmt.Println(result)

مقارنة طريقة المحاولة/الالتقاط

try:
    result = someCall()
    print(result)
except:
    print("Sorry") # a little divorced from potential origin of error
    sys.exit(1)

تحليل الحجة

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

برنامج الاتصال -flag arg1 arg2 يمنحنا التبديل الذي تم إعداد العلم للقيام به، وترجع لنا الموضعية := flags.Args() مصفوفة ["arg1", "arg2"]

ومع ذلك، فإن استدعاء البرنامج arg1 arg2 -flag لا يقوم بتبديل أي شيء من المفترض أن تفعله -flags، وبدلاً من ذلك يعطي المواضع كـ ["arg1"، "arg2"، "-flag"] حيث يكون العلم لم يتم تحليله.

قد يكون هذا مفيدًا لتمرير مكالمة فرعية مثل برنامج تلوين ls -l حيث يتم تمرير ls -l حرفيًا - حتى أتمكن من رؤية حالة الاستخدام.

إن معظم البرامج الموجودة تسمح لوسائط الإشارة في أي مكان حول العناصر الموضعية. ls dir1/ -l dir2/ هو نفسه ls -l dir1/ dir2/، وهذا هو التقليد الذي ينطبق على الغالبية العظمى من أوامر يونكس ولينكس.

قد يكون هذا أمرًا يجب الاعتياد عليه - ويستحق الاهتمام به.

الغرض وحالة استخدام Go

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

من خلال كمية الاستخدام الضئيلة للغاية حتى الآن، ومع مراعاة احتياجاتي المحددة، أستطيع أن أرى

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

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

توجه أحد الزملاء مؤخرًا إلى مكتبي في حالة من الفزع، محاولًا حل مشكلة الحصول على Java 17 على صورة Node الأساسية القديمة التي كانت تعتمد على Debian 10. إما أنه سيتعين عليه ترقية إصدار Node للحصول على صورة أساسية أحدث، أو استخدام صورة أساسية جديدة لديبيان وتثبيت Node يدويًا، أو البحث في الإنترنت عن مستودع مخصص يستضيفه الخير يعرف من بحق الخير يعرف. -إذا تم اختراق Java 17 والتي سيتم تشغيلها على Debian 10.

كم سيكون الأمر أسهل إذا لم يكن للبرنامج المنشور مثل هذه التبعيات المتضاربة في وقت التشغيل...

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

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

بيان الافراج تم نشر هذه المقالة على: https://dev.to/taikedz/baby-steps-with-go-3ibl?1 إذا كان هناك أي انتهاك، يرجى الاتصال بـ [email protected] لحذفه
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3