Go Academy · درس

تعريف الواجهات وتنفيذها

الامتثال الضمني والواجهة الفارغة

الدرس 1 من 414 خطوة

تعريف الواجهات وتنفيذها درس مجاني في Go Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Go Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Go Academy 4 دروس في المجموع.

ما الواجهة؟

الـواجهة في Go هي مجموعة من تواقيع الأساليب. أي نوع ينفّذ جميع تلك الأساليب يستوفي الواجهة ضمنيًا — ولا حاجة إلى الكلمة المفتاحية implements. ويُسمى هذا التنميط البنيوي أو تنميط البطة.

تعريف واجهة

عرّف واجهة باستخدام الكلمة المفتاحية type:

package main
import "fmt"

type Shape interface {
    Area() float64
    Perimeter() float64
}

type Circle struct{ Radius float64 }
func (c Circle) Area() float64      { return 3.14159 * c.Radius * c.Radius }
func (c Circle) Perimeter() float64 { return 2 * 3.14159 * c.Radius }

func main() {
    var s Shape = Circle{5}
    fmt.Printf("Area: %.2f\n", s.Area())
}

الاستيفاء الضمني

لا حاجة إلى التصريح بالنية. فإذا كان لدى النوع الأساليب الصحيحة، فإنه يستوفي الواجهة تلقائيًا:

package main
import "fmt"

type Greeter interface{ Greet() string }

type English struct{}
func (e English) Greet() string { return "Hello" }

type Spanish struct{}
func (s Spanish) Greet() string { return "Hola" }

func say(g Greeter) { fmt.Println(g.Greet()) }

func main() {
    say(English{})
    say(Spanish{})
}

الواجهة الفارغة

يستوفي كل نوع interface{} (أو any في Go 1.18+) . وتُستخدم عندما يكون النوع غير معروف في وقت الترجمة:

package main
import "fmt"

func printAny(v any) { fmt.Printf("%T: %v\n", v, v) }

func main() {
    printAny(42)
    printAny("hello")
    printAny([]int{1,2,3})
}

قيم الواجهة

تحتوي قيمة الواجهة على شيئين: نوع ملموس وقيمة ملموسة. أما الواجهة nil فتكون قيمتاها كلتاهما nil:

package main
import "fmt"

type Animal interface{ Sound() string }
type Dog struct{}
func (d Dog) Sound() string { return "woof" }

func main() {
    var a Animal
    fmt.Println(a == nil) // true
    a = Dog{}
    fmt.Println(a == nil) // false
    fmt.Println(a.Sound())
}

استيفاء واجهات متعددة

يمكن لنوع واحد استيفاء واجهات متعددة في الوقت نفسه:

package main
import "fmt"

type Reader interface{ Read() string }
type Writer interface{ Write(string) }
type ReadWriter interface{ Reader; Writer }

type File struct{ content string }
func (f *File) Read() string       { return f.content }
func (f *File) Write(s string)     { f.content = s }

func main() {
    var rw ReadWriter = &File{}
    rw.Write("hello")
    fmt.Println(rw.Read())
}

إسناد الواجهات

يمكن لواجهة أوسع أن تحتوي على قيمة ملموسة أضيق. ويتطلب الإسناد بين أنواع الواجهات أن يستوفي النوع الملموس الواجهتين كلتيهما:

package main
import "fmt"

type Stringer interface{ String() string }

type Point struct{ X, Y int }
func (p Point) String() string { return fmt.Sprintf("(%d,%d)", p.X, p.Y) }

func main() {
    var s Stringer = Point{3, 4}
    fmt.Println(s.String())
}

فخ الواجهة nil

لا تساوي الواجهة غير nil التي تحتوي على قيمة ملموسة تساوي nil القيمة nil:

package main
import "fmt"

type MyErr struct{}
func (e *MyErr) Error() string { return "oops" }

func bad() error {
    var e *MyErr // nil pointer
    return e     // returns non-nil interface!
}

func main() {
    err := bad()
    fmt.Println(err == nil) // false — common gotcha
}

الواجهات تتيح قابلية الاختبار

يتيح تعريف الاعتماديات كواجهات استبدال التطبيقات الفعلية بمحاكيات في الاختبارات:

package main
import "fmt"

type EmailSender interface{ Send(to, body string) error }

type MockSender struct{ Sent []string }
func (m *MockSender) Send(to, body string) error {
    m.Sent = append(m.Sent, to)
    return nil
}

func notify(s EmailSender, addr string) { s.Send(addr, "hello") }

func main() {
    mock := &MockSender{}
    notify(mock, "a@b.com")
    fmt.Println(mock.Sent) // [a@b.com]
}

اقبل الواجهات وأعد البنى

من أفضل ممارسات Go أن تكون معلمات الدوال واجهات (لتحقيق المرونة)، وأن تكون أنواع الإرجاع أنواعًا ملموسة (ليعرف المستدعون ما يحصلون عليه):

package main

type Logger interface{ Log(string) }

type FileLogger struct{}
func (f *FileLogger) Log(s string) {}

func NewFileLogger() *FileLogger { // returns concrete
    return &FileLogger{}
}

func process(l Logger) {} // accepts interface

func main() { process(NewFileLogger()) }

أبقِ الواجهات صغيرة

تفضّل مكتبة Go القياسية الواجهات الصغيرة جدًا: تحتوي io.Reader على أسلوب واحد، وكذلك io.Writer. فالواجهات الصغيرة أسهل في التركيب والمحاكاة.

تحقّق سريع

هل يحتاج النوع إلى التصريح بأنه ينفّذ واجهة؟

مراجعة: الواجهات

أهم النقاط:

  • تعرّف الواجهات السلوك، لا البيانات
  • الاستيفاء ضمني — ولا توجد كلمة مفتاحية implements
  • تقبل الواجهة الفارغة (any) كل نوع
  • انتبه إلى فخ الواجهة nil
  • أبقِ الواجهات صغيرة ومركّزة

مهمة تدريبية

عرّف واجهة Storage باستخدام Save(key, value string) error وLoad(key string) (string, error). نفّذها باستخدام MemStorage مستندة إلى خريطة، ثم اختبرها.

البدء مجانًا

تعلم Go مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
51
الدروس
203

الأسئلة الشائعة

هل درس «تعريف الواجهات وتنفيذها» مجاني؟

نعم — نص درس «تعريف الواجهات وتنفيذها» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Go Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Go Academy 4 دروس في المجموع.

ماذا ستتعلم في «تعريف الواجهات وتنفيذها»؟

الامتثال الضمني والواجهة الفارغة تتمرن على Go Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Go Academy؟

لا تُشترط خبرة سابقة. Go Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «تعريف الواجهات وتنفيذها»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Go Academy هذا؟

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

جميع الدروس في هذه الدورة

  1. تعريف الواجهات وتنفيذها
  2. واجهات مكتبة Go القياسية الأساسية
  3. تأكيدات الأنواع وعبارات type switch
  4. تركيب الواجهات وأفضل الممارسات
← العودة إلى Go Academy