يحتوي Go على أنواع قوية وثابتة ولا يدعم الأدوية الجنيسة ، فكيف يمكننا تحديد هياكل وخوارزميات بيانات الأغراض العامة التي يمكن تطبيقها على أكثر من نوع واحد؟interface{}
s ليست الحل ، لأنها تتطلب الإرسال ونفقد الكثير من مزايا الكتابة الثابتة القوية.الحل هو توليد الكود، لأنه يسمح بالحصول على فحوصات وقت التجميع والسلامة ، وأداء أعلى.
لم أجد هذه المعلومات يمكن الوصول إليها بسهولة عند البحث عن موضوعات إنشاء الكود ، لكنني عثرت على حالات وسيناريوهات استخدام أكثر تعقيدًا ، لذا ها هي موضحة باللغة الإنجليزية البسيطة.
مشكلة:
أريد أنتنفيذ بنية البيانات(الأمر نفسه ينطبق على الخوارزمية)بأكثر الطرق عموميةمع Go و وإنشاء تطبيقات خاصة بالنوع يمكنني إعادة استخدامها بسهولة.
المحلول:
استخدامجيني، لا يمكن أن يكون هذا أبسط:
- يستورد
genny/generic
- حدد نوعًا واحدًا أو أكثر مثل
generic.Type
، على سبيل المثال الاتصال بهمItem
أوType
- استخدم هذه الأنواع في التعليمات البرمجية الخاصة بك
- يركض
genny
لإنشاء التنفيذ الخاص بالنوع
مثال
تحقق من هذا المثال البسيط ، وهو إصدار مقتطع من ملفتعيين تنفيذ بنية البيانات في Go:
// Package set creates a ItemSet data structure for the Item type
package set
import “github.com/cheekybits/genny/generic”
// Item the type of the Set
type Item generic.Type
// ItemSet the set of Items
type ItemSet struct {
items map[Item]bool
}
// Add adds a new element to the Set. Returns the Set.
func (s ItemSet) Add(t Item) ItemSet {
if s.items == nil {
s.items = make(map[Item]bool)
}
_, ok := s.items[t]
if !ok {
s.items[t] = true
}
return s
}
// Clear removes all elements from the Set
func (s ItemSet) Clear() {
(s).items = make(map[Item]bool)
}
عن طريق الركض
genny -in set.go -out gen-set.go gen "Item=string,int"
في سطر الأوامر الآن ، إذا تم استدعاء الملفset.go
سوف تولدgen-set.go
والتي تحتوي على ما يلي:
// This file was automatically generated by genny.
// Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny
// Package Set creates a StringSet data structure for the string type
package set
// StringSet the set of Strings
type StringSet struct {
items map[string]bool
}
// Add adds a new element to the Set. Returns the Set.
func (s StringSet) Add(t string) StringSet {
s.items[t] = true
return s
}
// Clear removes all elements from the Set
func (s StringSet) Clear() {
(s).items = make(map[string]bool)
}
// Delete removes the string from the Set and returns Has(string)
func (s StringSet) Delete(item string) bool {
ret := (s).Has(item)
if ret {
delete((*s).items, item)
}
return ret
}
// Has returns true if the Set contains the string
func (s StringSet) Has(item string) bool {
return (s).items[item]
}
// Strings returns the string(s) stored
func (s *StringSet) Strings() []string {
items := []string{}
for i := range s.items {
items = append(items, i)
}
return items
}
// Package Set creates a IntSet data structure for the int type
// IntSet the set of Ints
type IntSet struct {
items map[int]bool
}
// Add adds a new element to the Set. Returns the Set.
func (s IntSet) Add(t int) IntSet {
s.items[t] = true
return s
}
// Clear removes all elements from the Set
func (s IntSet) Clear() {
(s).items = make(map[int]bool)
}
// Delete removes the int from the Set and returns Has(int)
func (s IntSet) Delete(item int) bool {
ret := (s).Has(item)
if ret {
delete((*s).items, item)
}
return ret
}
// Has returns true if the Set contains the int
func (s IntSet) Has(item int) bool {
return (s).items[item]
}
// Ints returns the int(s) stored
func (s *IntSet) Ints() []int {
items := []int{}
for i := range s.items {
items = append(items, i)
}
return items
}
كما ترون،genny
خلقStringSet
وIntSet
الهياكل منItemSet
** ، لأن روى ذلكItem=string,int
.
كما أنها خلقت أساليب الهيكلالتي تؤلف تطبيقات المجموعة لدينا.
إذا أردنا إضافة مجموعة أخرى من الأنواع إلى تطبيقنا ، فيمكننا تعديل الأمر وتشغيله مرة أخرى.
يستخدمgo generate
يمكنك أيضًا أتمتة ذلك عن طريق إضافة تعليق أعلى الملف ، أسفل مستند الحزمة ، مثل:
// go:generate genny -in=$GOFILE -out=gen-$GOFILE gen "Item=string,int"
هذا يخبرناgo generate
، من خلال مساعدةgenny
، لإنشاء نسخة مترجمةItem
إلىstring
، ونسخة ثانية للترجمةitem
إلىint
.
يركض
go generate
للحصول علىgen-set.go
ملف ، مع مجموعات سلسلة وكتف.
اختبارات
هام: التنفيذ العام لهيكل البيانات أعلاهيجمع ويمكن اختبارهابنفس سهولة التنفيذ الملموس الناتج عنgo generate
، حتى نتمكن من إجراء اختبارات مقابل التنفيذ العام ، وكذلك الاختبارات الخاصة بالنوع.
المزيد من دروس Go:
- استخدام وكيل NGINX العكسي لخدمة خدمات Go
- عمل نسخة من هيكل في Go
- أساسيات Go Web Server
- فرز نوع الخريطة في Go
- الذهاب المؤشرات باختصار
- وأوضح Go Tags
- الذهاب تنسيق التاريخ والوقت
- معالجة JSON باستخدام Go
- وظائف متنوعة
- ورقة الغش Go Strings
- شرح واجهة Go Empty
- تصحيح الأخطاء الذهاب مع VS Code و Delve
- تقوم Named Go بإرجاع المعلمات
- توليد أرقام وسلاسل عشوائية في Go
- بنية نظام الملفات لمشروع Go
- تم تنفيذ خوارزمية البحث الثنائي في Go
- استخدام إشارات سطر الأوامر في Go
- أوضح جوباته
- أنشئ تطبيق Command Line باستخدام Go: lolcat
- إنشاء أمر CLI باستخدام Go: cowsay
- استخدام أنابيب شل مع Go
- Go CLI التعليمي: Fortune clone
- ضع قائمة بالملفات في مجلد باستخدام Go
- استخدم Go للحصول على قائمة بالمستودعات من GitHub
- اذهب ، قم بإلحاق شريحة من السلاسل بملف
- اذهب ، قم بتحويل سلسلة إلى شريحة بايت
- تصور مساهمات Git المحلية الخاصة بك مع Go
- الشروع في استخدام Go CPU وتوصيف الذاكرة
- حل الخطأ "لا يدعم الفهرسة" في برنامج Go
- قياس وقت التنفيذ في برنامج Go
- بناء زاحف الويب باستخدام Go لاكتشاف العناوين المكررة
- Go Best Practices: المؤشر أم مستقبلات القيمة؟
- Go Best Practices: هل يجب عليك استخدام طريقة أم دالة؟
- Go Data Structures: Set
- ورقة الغش في خرائط Go
- إنشاء تطبيقات لأنواع عامة في Go
- Go Data Structures: القاموس
- Go هياكل البيانات: Hash Table
- تنفيذ مستمعي الأحداث في الانتقال عبر القنوات
- Go Data Structures: Stack
- Go هياكل البيانات: قائمة الانتظار
- Go Data Structures: Binary Search Tree
- Go هياكل البيانات: رسم بياني
- Go Data Structures: قائمة مرتبطة
- الدليل الكامل إلى Go Data Structures
- مقارنة قيم Go
- هل Go موجه للكائن؟
- العمل مع قاعدة بيانات SQL في Go
- استخدام متغيرات البيئة في Go
- Go البرنامج التعليمي: REST API مدعوم من PostgreSQL
- تمكين CORS على خادم Go Web
- نشر تطبيق Go في حاوية Docker
- لماذا Go هي لغة قوية للتعلم كمطور PHP
- اذهب ، قم بإزالة io.Reader.ReadString حرف سطر جديد
- اذهب ، كيف تراقب التغييرات وتعيد بناء برنامجك
- اذهب وعد الأشهر منذ تاريخ
- الوصول إلى معلمات HTTP POST في Go