الجزء التوضيحي من استيراد الحزم إلى 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 تقوم الحزمة 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
كما ترى من الإخراج ، عند استيراد الحزم ذات الحقول المتقاطعة في النطاق الحالي ، نحصل على خطأ في الترجمة.
لذلك ، فكر مرة أخرى قبل استخدام مثل هذا الاستيراد - يمكنك الحصول على خطأ بشكل غير متوقع تمامًا.
المجموع
على الرغم من قيود بناء الجملة الصارمة ، يمكنك القيام بالكثير من الأشياء غير القياسية في Go. توضح ميزات الاستيراد التي تمت مناقشتها أعلاه أنه من خلال بضعة عوامل تشغيل ، يمكنك تغيير سلوك البرنامج كثيرًا. الشيء الرئيسي ، عند استخدام كل هذه الفرص ، هو عدم إطلاق النار على نفسك . وتذكر أنه من الأفضل كتابة كود بسيط ومفهوم من رمز معقد و "رائع".
ملاحظة
أمثلة على التعليمات البرمجية للعب بها موجودة على github .