4 طرق لاستيراد حزمة في Go

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


  package main import ( "github.com/vigo5190/goimports-example/a" foo "github.com/vigo5190/goimports-example/a" . "github.com/vigo5190/goimports-example/b" _ "github.com/vigo5190/goimports-example/c" ) 

إذا كان الاستيراد القياسي ، استيراد مع مرادف و _ التقيت ، ثم الاستيراد من . أنا لم أر من قبل.


بالنسبة للمبتدئين ، تجدر الإشارة إلى كيفية إطلاق البرامج على Go.
أول وأهم شيء - في جذر المشروع (للمكتبات والحزم خلاف ذلك) يكمن ملف main.go ، والذي ، عند تطويره ، يتم تشغيله بواسطة الأمر


 go run main.go 

السمة المميزة لهذا الملف هي أن الحزمة المعلنة فيه يجب أن تكون main .


 package main import ( "fmt" ) func main() { fmt.Println("Hello habr.com!") } 

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


أمثلة الحزمة


تصدر الحزمة a المتغير فقط ، ولكنها لا تهيئه.


github.com/vigo5190/goimports-example/a
 package a var Foo string 

تقوم الحزمة b بتصدير المتغير وتهيئته إلى init() .


github.com/vigo5190/goimports-example/b
 package b var Foo string func init() { Foo = "bar" } 

تقوم الحزمة c بتصدير المتغير ، وتهيئته إلى init() وعرض القيمة في stdout.


github.com/vigo5190/goimports-example/c
 package c import "fmt" var Foo string func init() { Foo = "bar" fmt.Printf("%#v\n", Foo) } 

استيراد "بسيط"


في هذا المثال ، نستورد حزمتين ونخرج قيم المتغيرات المصدرة إلى stdout.


 package main import ( "fmt" "github.com/vigo5190/goimports-example/a" "github.com/vigo5190/goimports-example/b" ) func main() { fmt.Printf("%#v\n", a.Foo) fmt.Printf("%#v\n", b.Foo) } 

نحصل


 go run main.go "" "bar" 

ما يحدث بالفعل في هذا الرمز. في قسم import ، b استيراد حزمتين a و b . في الحزمة a يتم التصريح عن متغير بقيمة افتراضية (للسلاسل - سلسلة فارغة). في الحزمة b ، تمت تهيئة القيمة المتغيرة في init() بالقيمة "bar" . للوصول إلى متغيرات كل حزمة ، استخدم إدخال النموذج <_>.<_> .


استيراد مرادف


 package main import ( "fmt" "github.com/vigo5190/goimports-example/a" foo "github.com/vigo5190/goimports-example/b" bar "github.com/vigo5190/goimports-example/a" ) func main() { fmt.Printf("%#v\n", a.Foo) fmt.Printf("%#v\n", foo.Foo) fmt.Printf("%#v\n", bar.Foo) } 

نحصل


 go run main.go "" "bar" "" 

كما ترى من المثال ، b تعيين الحزمة b مرادف foo . في هذه الحالة ، a استيراد الحزمة a عدة مرات - المرة الثانية تحت bar الاسم المستعار.


يتم استيراد الحزم عن طريق تحديد المرادفات في عدة حالات:


  • اسم الحزمة المستوردة غير مريح / قبيح / ... وأريد استخدام آخر ؛
  • يتقاطع اسم المستورد مع اسم حزمة أخرى ؛
  • أريد استبدال الحزمة بسلاسة - يجب أن تتطابق واجهات الحزمة.

مثال للاستخدام المبرر لمرادف

على سبيل المثال ، عند استيراد github.com/sirupsen/logrus :


 package db import( log "github.com/sirupsen/logrus" ) 

تسطير الاستيراد


 package main import ( "fmt" "github.com/vigo5190/goimports-example/a" _ "github.com/vigo5190/goimports-example/c" ) func main() { fmt.Printf("%#v\n", a.Foo) } 

نحصل


 go run main.go "bar" "" 

كما يظهر الرمز ، نستورد حزمتين: a و c . في هذه الحالة ، تكون الحزمة c مسبوقة بـ _ ولا يتم استخدام الحزمة نفسها بأي شكل من الأشكال. يتم استخدام هذه التقنية لتنفيذ init() من حزمة.


في مثالنا ، ظهر "bar" في الإخراج على السطر الأول ، لأن هذا الإخراج في دالة تهيئة الحزمة c .


مثال للاستخدام المبرر

على سبيل المثال ، عند استيراد github.com/lib/pq :


 package db import( _ "github.com/lib/pq" ) 

في init() lib/pq الكود هو:


 func init() { sql.Register("postgres", &Driver{}) } 

التي ستسجل السائق.


استيراد نقطة ج


 package main import ( "fmt" "github.com/vigo5190/goimports-example/a" . "github.com/vigo5190/goimports-example/b" ) func main() { fmt.Printf("%#v\n", a.Foo) fmt.Printf("%#v\n", Foo) } 

نحصل


 go run main.go "" "bar" 

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


يجب استخدام هذا الخيار بعناية فائقة - مثال أدناه.


مثال 1
 package main import ( . "fmt" ) func main() { Println("Hello, habr.com!") } 

نحصل على:


 Hello, habr.com! 

مثال 2
 package main import ( . "fmt" . "math" ) func main() { Printf("%v\n", Sqrt(9)) } 

نحصل على:


 3 

الاستيراد بالنقطة (والخطأ)


 package main import ( "fmt" . "github.com/vigo5190/goimports-example/a" . "github.com/vigo5190/goimports-example/b" ) func main() { fmt.Printf("%#v\n", Foo) } 

نحصل


 go run main.go # command-line-arguments ./main.go:7:2: Foo redeclared during import "github.com/vigo5190/goimports-example/b" previous declaration during import "github.com/vigo5190/goimports-example/a" ./main.go:7:2: imported and not used: "github.com/vigo5190/goimports-example/b" 

كما ترى من الإخراج ، عند استيراد الحزم ذات الحقول المتقاطعة في النطاق الحالي ، نحصل على خطأ في الترجمة.


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


المجموع


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


ملاحظة


أمثلة على التعليمات البرمجية للعب بها موجودة على github .

Source: https://habr.com/ru/post/ar413563/


All Articles