تُعَدّ الحزمة مجموعةً من الملفات الموجودة ضمن مجلد واحد والمتضمّنة لتعليمة الحزمة نفسها في بدايتها، ويمكنك تضمين العديد من الحزم ضمن برنامجك عند الحاجة لبناء برمجيات أكثر تعقيدًا.
تكون بعض الحزم موجودةً في مكتبة جو القياسية وبعضها الآخر يمكنك تثبيته من خلال الأمر go get
، كما يمكنك أيضًا إنشاء الحزم الخاصة بك من خلال بناء ملفات لغة جو التي تحتاجها ووضعه ضمن المجلد نفسه مع الالتزام بكتابة تعليمة الحزمة الضرورية في بداية كل ملف، كما ستتعلم في هذا المقال كيفية إنشاء حزم لغة جو الخاصة بك لاستخدامها في برامجك.
المتطلبات
- أن يكون لديك مساحة عمل خاصة في لغة جو، فإذا لم يكن لديك، فاتبع سلسلة المقالات التالية، فقد تحدّثنا عن ذلك في بداية السلسلة
- تثبيت لغة جو Go وإعداد بيئة برمجة محلية على أبونتو Ubuntu
- تثبيت لغة جو وإعداد بيئة برمجة محلية على نظام ماك macOS
- تثبيت لغة جو وإعداد بيئة برمجة محلية على ويندوز
- يُفضّل أن تكون قد اطلعت أيضًا على المقالة السابقة
- يُفضّل أن يكون لديك معرفة حول متغير البيئة أو مسار البيئة GOPATH، ويمكنك الاطلاع على مقال التعرّف على GOPATH
كتابة واستيراد الحزم
تشبه كتابة الحزم كتابة أيّ برنامج آخر في لغة جو، ويمكن أن تتضمن الحزم دوالًا أو متغيرات أو أنواع بيانات خاصة يمكنك استخدامها في برنامجك لاحقًا.
يجب أن تكون ضمن مساحة العمل الخاصة بك قبل إنشاء حزم جديدة، وهذا يعني أن تكون ضمن مسار البيئة gopath
، ففي هذا المقال مثلًا سنُنشئ الحزمة greet
، لذا سنُنشئ المجلد greet ضمن مسار البيئة وضمن مساحة العمل الخاصة بك، فإذا كنا ضمن مساحة العمل gopherguides
وأردنا إنشاء الحزمة greet
ضمنها أثناء استخدام جيت هاب Github على أساس مستودع تعليمات برمجية، فسيبدو المجلد كما يلي:
└── $GOPATH └── src └── github.com └── gopherguides
ستكون الحزمة greet
ضمن المجلد gopherguides:
└── $GOPATH └── src └── github.com └── gopherguides └── greet
يمكننا الآن إنشاء أول ملف في الحزمة، ويسمى الملف الأساسي -ويسمى أيضًا نقطة الدخول entry point- في الحزمة عادةً باسم الحزمة نفسها، إذًا سنُنشئ الملف greet.go ضمن المجلد greet كما يلي:
└── $GOPATH └── src └── github.com └── gopherguides └── greet └── greet.go
يمكننا بعد إنشاء الملف كتابة التعليمات البرمجية التي نريدها ضمنه، ويكون الهدف من هذه التعليمات عادةً هو الاستخدام في مكان آخر من المشروع، وفي هذه الحالة سننشئ دالة Hello تطبع Hello World، لذا افتح الملف greet.go من خلال محرر الشيفرات الخاص بك واكتب ضمنه التعليمات التالية:
package greet import "fmt" func Hello() { fmt.Println("Hello, World!") }
يجب دومًا أن نبدأ باسم الحزمة التي نعمل ضمنها لكي نُخبر المصرِّف أنّ هذا الملف هو جزء من الحزمة، لذا كتبنا الكلمة المفتاحية package
متبوعةً باسم الحزمة:
package greet
ثم نكتب اسم الحزم التي نحتاج إلى استخدامها ضمن الملف من خلال وضع أسمائها بعد الكلمة المفتاحية import
، وهنا نحتاج إلى حزمة fmt
فقط:
import "fmt"
أخيرًا سنكتب الدالة Hello
التي تستخدِم الحزمة fmt
لتنسيق طباعة جملة الخرج:
func Hello() { fmt.Println("Hello, World!") }
نكون الآن قد انتهينا من إنشاء الملف الأول وأصبح بإمكاننا استخدام الدالة Hello
منه وفي المكان الذي نريده.
سنُنشئ الآن حزمةً جديدةً سنسميها example
، لذا يجب أن نُنشئ مجلدًا لها بالاسم نفسه، وسننشئه ضمن مساحة العمل نفسها gopherguides
:
└── $GOPATH └── src └── github.com └── gopherguides └── example
الآن وقد أصبح لديك مجلدًا خاصًا بالحزمة، بات بإمكانك إنشاء ملف نقطة الدخول، والذي سيكون ملفًا رئيسيًا -أي ملف تنفيذي-، لذا سنسميه main.go:
└── $GOPATH └── src └── github.com └── gopherguides └── example └── main.go
افتح الملف من محرر الشيفرات الخاص بك واكتب التعليمات التالية:
package main import "github.com/gopherguides/greet" func main() { greet.Hello() }
بما أن الدالة التي تريد استخدامها ضمن الملف الرئيسي موجودة ضمن حزمة أخرى، فسيتوجب عليك استدعاؤها من خلال ذكر اسم الحزمة أولًا متبوعًا بنقطة ثم اسم الدالة، فمثلًا وضعنا هنا اسم الحزمة greet
ثم نقطة ثم اسم الدالة ()greet.Hello
، ويمكنك الآن فتح الطرفية وتشغيل البرنامج ضمنها:
go run main.go
سيكون الخرج كما يلي:
Hello, World!
سنضيف بعض المتغيرات إلى ملف greet.go لتتعلم كيفية استخدام المتغيرات ضمن الحزمة:
package greet import "fmt" var Shark = "Sammy" func Hello() { fmt.Println("Hello, World!") }
ثم افتح الملف main.go وأضف التعليمة التالية (fmt.Println(greet.Shark
لاستدعاء المتغير Shark
داخل الدالة fmt.Println
، أي كما يلي:
package main import ( "fmt" "github.com/gopherguides/greet" ) func main() { greet.Hello() fmt.Println(greet.Shark) }
ثم شغّل الشيفرة مرةً أخرى:
$ go run main.go
ستحصل على الخرج التالي:
Hello, World! Sammy
أخيرًا، سننشئ نوع بيانات جديد ضمن ملف greet.go، إذ سننشئ نوع البيانات Octopus
الذي يتضمّن الحقلين name
و color
، كما سنعرّف دالةً تطبع هذه الحقول:
package greet import "fmt" var Shark = "Sammy" type Octopus struct { Name string Color string } func (o Octopus) String() string { return fmt.Sprintf("The octopus's name is %q and is the color %s.", o.Name, o.Color) } func Hello() { fmt.Println("Hello, World!") }
سننشئ الآن نسخةً من هذا النوع داخل الملف main.go:
package main import ( "fmt" "github.com/gopherguides/greet" ) func main() { greet.Hello() fmt.Println(greet.Shark) oct := greet.Octopus{ Name: "Jesse", Color: "orange", } fmt.Println(oct.String()) }
بمجرّد إنشاء نسخة من النوع Octopus
عند كتابة oct := greet.Octopus
يُصبح بإمكاننا الوصول إلى الداول والمتغيرات الموجودة ضمنه من الملف main، وبالتالي إمكانية استدعاء الدالة ()oct.String
من دون الحاجة لكتابة اسم الحزمة greet
، كما يمكنك الوصول إلى الحقول بالطريقة نفسها دون الحاجة إلى كتابة اسم الحزمة مثل oct.Color
.
يستخدِم التابع String
التي يتضمنها النوع Octopus
الدالة fmt.Sprintf
لإنشاء وإرجاع سلسلة في المكان الذي استُدعي فيه أي في هذه الحالة في الملف main
، وسنشغّل البرنامج الآن كما يلي:
$ go run main.go
يكون الخرج كما يلي:
Hello, World! Sammy The octopus's name is "Jesse" and is the color orange.
إذًا سيصبح لدينا دالة يمكن استخدامها حيثما نريد لطباعة معلومات عن نوع البيانات الذي عرّفناه من خلال تعريفنا للتابع String
ضمن النوع Octopus
، فإذا أردت تغيير سلوك هذا التابع لاحقًا، فيمكنك ببساطة تعديله فقط حيثما يكون.
تصدير الشيفرة
لاحظ أنّ كل التصريحات داخل الملف greet.go
تبدأ بمحرف كبير، ولا تمتلك لغة جو مفاهيم مُحددات الوصول العامة public
والخاصة private
والمحمية protected
كما في باقي اللغات، ويمكن التحكم بالرؤية في لغة جو من خلال الكتابة بمحارف كبيرة، فالمتغيرات أو الدوال أو الأنواع التي تبدأ بمحارف كبيرة تكون مرئيةً من خارج الحزمة -أي عامة- ويُعتبر عندها مُصدّرًا exported.
إذا أضفت تابعًا جديدًا إلى النوع Octopus
اسمه reset
، فستتمكّن من استدعائه من داخل الحزمة greet
، لكن لن تتمكن من استدعائه من الملف main.go لأنه خارج الحزمة greet
:
package greet import "fmt" var Shark = "Sammy" type Octopus struct { Name string Color string } func (o Octopus) String() string { return fmt.Sprintf("The octopus's name is %q and is the color %s.", o.Name, o.Color) } func (o *Octopus) reset() { o.Name = "" o.Color = "" } func Hello() { fmt.Println("Hello, World!") }
إذا حاولت استدعاء reset
من الملف main.go:
package main import ( "fmt" "github.com/gopherguides/greet" ) func main() { greet.Hello() fmt.Println(greet.Shark) oct := greet.Octopus{ Name: "Jesse", Color: "orange", } fmt.Println(oct.String()) oct.reset() }
ستحصل على الخطأ التالي والذي يقول أنه لا يمكن الإشارة إلى حقل أو دالة غير مصدرة:
oct.reset undefined (cannot refer to unexported field or method greet.Octopus.reset)
لتصدير دالة reset
من Octopus
، اجعل المحرف الأول من الدالة كبيرًا، أي Reset
:
package greet import "fmt" var Shark = "Sammy" type Octopus struct { Name string Color string } func (o Octopus) String() string { return fmt.Sprintf("The octopus's name is %q and is the color %s.", o.Name, o.Color) } func (o *Octopus) Reset() { o.Name = "" o.Color = "" } func Hello() { fmt.Println("Hello, World!") }
وبالتالي سيصبح بإمكانك استدعائها من الحزمة الأخرى بدون مشاكل:
package main import ( "fmt" "github.com/gopherguides/greet" ) func main() { greet.Hello() fmt.Println(greet.Shark) oct := greet.Octopus{ Name: "Jesse", Color: "orange", } fmt.Println(oct.String()) oct.Reset() fmt.Println(oct.String()) }
الآن إذا شغّلت البرنامج:
$ go run main.go
ستتلقى الخرج التالي:
Hello, World! Sammy The octopus's name is "Jesse" and is the color orange The octopus's name is "" and is the color .
نلاحظ من خلال استدعاء الدالة Reset
أن جميع بيانات الحقول Name
و Color
قد مسحتها، وعند استدعاء التابع String
لاتطبع شيئًا لأن الحقول السابقة قد أصبحت فارغةً.
الخاتمة
تشبه كتابة الحزم في لغة جو كتابة أيّ ملف في لغة جو، إلا أن وضعها في مجلد مُختلف سيسمح لك بعزل الشيفرة لإعادة استخدامها في مكان آخر، وقد تحدثنا في هذا المقال عن كيفية تعريف وإنشاء الحزم وكيفية الاستفادة منها في ملفات أخرى وأين يمكن وضعها للوصول إليها.
ترجمة -وبتصرُّف- للمقال How To Write Packages in Go لصاحبه Gopher Guides.
تعليقات
إرسال تعليق