البُنى المجهولة والتركيب
التضمين وإعادة استخدام الشيفرة المعتمدة على البُنى
البُنى المجهولة والتركيب درس مجاني في Go Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Go Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Go Academy 4 دروس في المجموع.
البنى المجهولة
لا تملك البنية المجهولة نوعًا مُسمّى. وتُعرَّف مباشرةً، وتفيد في البيانات قصيرة العمر، والاختبارات المعتمدة على الجداول، والتجميعات أحادية الاستخدام:
package main
import "fmt"
func main() {
point := struct{ X, Y int }{X: 3, Y: 7}
fmt.Println(point.X, point.Y)
}البنى المجهولة في الاختبارات المعتمدة على الجداول
يستخدم أسلوب شائع في Go شريحةً من البنى المجهولة للاختبارات المعتمدة على الجداول:
package main
import "fmt"
func double(n int) int { return n * 2 }
func main() {
tests := []struct{ input, want int }{
{1, 2}, {5, 10}, {0, 0},
}
for _, tt := range tests {
got := double(tt.input)
if got != tt.want {
fmt.Printf("FAIL: double(%d) = %d, want %d\n", tt.input, got, tt.want)
}
}
fmt.Println("all tests passed")
}تضمين البنى
يؤدي تضمين نوع داخل بنية إلى إتاحة حقوله وطرقه للبنية الخارجية:
package main
import "fmt"
type Animal struct{ Name string }
func (a Animal) Speak() string { return a.Name + " speaks" }
type Dog struct {
Animal // embedded
Breed string
}
func main() {
d := Dog{Animal: Animal{"Rex"}, Breed: "Labrador"}
fmt.Println(d.Name) // promoted field
fmt.Println(d.Speak()) // promoted method
}تضمين أنواع متعددة
يمكن للبنية تضمين أنواع متعددة. ويجب حل التعارضات (مثل تطابق اسم الحقل أو الطريقة) بشكل صريح:
package main
import "fmt"
type Logger struct{}
func (Logger) Log(s string) { fmt.Println("[LOG]", s) }
type Metrics struct{}
func (Metrics) Count() int { return 42 }
type Service struct {
Logger
Metrics
Name string
}
func main() {
svc := Service{Name: "auth"}
svc.Log("started") // from Logger
fmt.Println(svc.Count()) // from Metrics
}التضمين مقابل التوريث
لا تحتوي Go على توريث للفئات. التضمين هو تركيب:
- يتيح التضمين الحقول والطرق للبنية الخارجية، لكن النوع الخارجي ليس نوعًا فرعيًا
- لا يمكنك تمرير
Dogحيث يُتوقعAnimal - استخدم الواجهات لتعدد الأشكال، والتضمين لإعادة استخدام الشيفرة
تجاوز الطرق المتاحة عبر التضمين
يمكن للبنية الخارجية حجب طريقة مضمنة بتعريف طريقة خاصة بها:
package main
import "fmt"
type Base struct{}
func (Base) Hello() string { return "Base hello" }
type Child struct{ Base }
func (Child) Hello() string { return "Child hello" } // shadows Base.Hello
func main() {
c := Child{}
fmt.Println(c.Hello()) // Child hello
fmt.Println(c.Base.Hello()) // Base hello (explicit)
}بنية مجهولة للإعدادات
استخدم بنية مجهولة لتجميع إعدادات مترابطة من دون تعريف نوع مُسمّى:
package main
import "fmt"
func main() {
cfg := struct {
Host string
Port int
TLS bool
}{
Host: "api.example.com",
Port: 443,
TLS: true,
}
fmt.Println(cfg)
}تضمين واجهة
يفيد تضمين واجهة في بنية في إنشاء محاكاة وتنفيذات افتراضية:
package main
import "fmt"
type Reader interface{ Read() string }
type Mock struct{ Reader } // embed interface
func main() {
m := Mock{}
fmt.Printf("%T\n", m.Reader) // <nil> — not set
// Assign a real impl at test time:
_ = m
}مشكلات تركيب البنى
انتبه إلى ما يلي:
- المحددات الملتبسة عندما يكون لنوعين مضمنين اسم الحقل أو الطريقة نفسه
- قد يؤدي المؤشر المضمن الذي قيمته nil إلى حدوث panic عند استدعاء طرقه
- لا تنسَ أن التضمين ليس توريثًا — فلا يمكنك إحلال النوع الخارجي محل النوع المضمن
مقارنة البنى المجهولة
يمكن إسناد بنيتين مجهولتين لهما أسماء الحقول وأنواعها نفسها إلى إحداهما الأخرى إذا تطابقت وسومهما أيضًا:
package main
import "fmt"
func main() {
a := struct{ X, Y int }{1, 2}
b := struct{ X, Y int }{1, 2}
fmt.Println(a == b) // true
}تحقق سريع
ما الذي يحققه تضمين نوع في بنية؟
مراجعة: التركيب
أهم النقاط:
- تُعد البنى المجهولة مناسبة للاختبارات المعتمدة على الجداول والبيانات قصيرة العمر
- يتيح التضمين الحقول والطرق — وهو تركيب وليس توريثًا
- يمكن للأنواع الخارجية حجب الطرق المضمنة
- حل المحددات الملتبسة بشكل صريح
- استخدم الواجهات لتعدد الأشكال
مهمة تدريبية
أنشئ بنية TimestampedRecord تتضمن Timestamp struct{ CreatedAt, UpdatedAt string } وData struct{ Key, Value string }. أنشئ مثيلًا منها واطبع جميع الحقول المتاحة عبر التضمين.
الأسئلة الشائعة
هل درس «البُنى المجهولة والتركيب» مجاني؟
نعم — نص درس «البُنى المجهولة والتركيب» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Go Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Go Academy 4 دروس في المجموع.
ماذا ستتعلم في «البُنى المجهولة والتركيب»؟
التضمين وإعادة استخدام الشيفرة المعتمدة على البُنى تتمرن على Go Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Go Academy؟
لا تُشترط خبرة سابقة. Go Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «البُنى المجهولة والتركيب»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Go Academy هذا؟
نعم. كل درس في Go Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- تعريف البُنى واستخدامها
- الطرائق على البُنى
- أنماط المُنشئات
- البُنى المجهولة والتركيب