English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

دليل أساسي في Golang

استبدالات التحكم في Golang

functions & methods في Golang

Structs في Golang

قطع & Arrays في Golang

كلمات Golang

مؤشرات Golang

واجهات Golang

إConcurrency في Golang

استثناءات Golang

متنوعات أخرى في Golang

واجهة (Interfaces) لغة Go

واجهات لغة Go تختلف عن لغات أخرى. في لغة Go، واجهة هي نوع مخصص تستخدم لتعريف مجموعة من معادلات الطريقة، وهي نوع مبدئي، لذلك لا يمكنك إنشاء مثيل للواجهة. ولكن يمكنك إنشاء متغيرات نوع واجهة، ويمكنك تخصيصها بمثال نوعي يحتوي على الطرق المطلوبة. بمعنى آخر، واجهة هي مجموعة من الطرق ونوع مخصص.

كيفية إنشاء واجهة؟

في لغة Go، يمكنك استخدام النحو التالي لإنشاء واجهة:

type interface_name interface{
    // معادلة الطريقة
}

مثال:

// إنشاء واجهة
type myinterface interface{
    //الطريقة
    fun1() int
    fun2() float64
}

في هذا المثال، يحتوي اسم الواجهة على كلمات المفتاح type وinterface بينهما، ويحتوي على معادلة الطريقة بين الأقواس.

كيفية تنفيذ الواجهة؟

في لغة Go، لتنفيذ واجهة، يجب تنفيذ جميع الطرق المعلن عنها في الواجهة. واجهات لغة Go هي تنفيذ غير صريح. مثل لغات أخرى، فإنها لا تحتوي على كلمات مفتاحية محددة لتنفيذ الواجهة. مثل المثال التالي:

// شرح برنامج Golang كيف
// تنفيذ واجهة
package main
import "fmt"
// إنشاء واجهة
type tank interface {
    //الطريقة
    Tarea() float64
    Volume() float64
}
type myvalue struct {
    radius float64
    height float64
}
// طريقة التنفيذ
// واجهة الحاوية (Tank)
func (m myvalue) Tarea() float64 {
    العودة 2*m.radius*m.height + 2*3.14*m.radius*m.radius
}
func (m myvalue) Volume() float64 {
    العودة 3.14 * m.radius * m.radius * m.height
}
func main() {
    // زيارته واستخدام واجهة الحاوية
    var t tank
    t = myvalue{10, 14}
    fmt.Println("مساحة البرميل:", t.Tarea())
    fmt.Println("سعة البرميل:", t.Volume())
}

الإخراج:

مساحة البرميل: 908
سعة البرميل: 4396

ملاحظات

  • قيمة الواجهة هي nil.

  • عندما تحتوي الواجهة على بدون أي طريقة، تُدعى هذه الواجهة واجهة فارغة. لذلك، تنفذ جميع الأنواع الواجهة الفارغة.

    النحو:

    interface{}
  • نوع الواجهة:يوجد نوعان للواجهة، واحد ثابت، والآخر ديناميكي. النوع الثابت هو الواجهة نفسها، مثل tank في المثال التالي. ولكن الواجهة ليس لديها قيمة ثابتة، لذا دائمًا ما تشير إلى قيمة ديناميكية.
    م変ي الواجهة التي تحتوي على قيمة النوع الذي يمثل الواجهة، لذلك تُدعى قيمة هذا النوع قيمة ديناميكية، والنوع هو نوع ديناميكي. ويُدعى أيضًا قيمة مادية ونوع مادي.

    //شرح مفاهيم برنامج Go
    //القيمة الديناميكية والنوع
    package main
    import "fmt"
    //إنشاء واجهة
    type tank interface {
        //الطريقة
        Tarea() float64
        Volume() float64
    }
    func main() {
        var t tank
        fmt.Println("قيمة واجهة tank هي: ", t)
        fmt.Printf("نوع tank هو: %T ", t)
    }

    الإخراج:

    قيمة واجهة tank هي: <nil>
    نوع tank هو: <nil>

    في المثال السابق، هناك واجهة تُدعى tank. في هذا المثال،fmt.Println("قيمة واجهة tank هي: ", t) الجملة تعود بقيمة الواجهة الديناميكية، بينما تعود جملة fmt.Printf("نوع tank هو: %T ", t) بنوع الواجهة الديناميكي، وهو nil، لأن الواجهة هنا لا تعرف من الذي يقوم بتنفيذه.

  • استدلال النوع:في لغة Go، يتم تطبيق استدلال النوع على قيم الواجهة. بمعنى آخر، هو عملية استخراج قيمة الواجهة.

    النحو:

    a.(T)

    في هذا السياق، a هو قيمة أو تعبير واجهة، T هو النوع الذي يُدعى أيضًا باستدلال النوع. يستخدم استدلال النوع لتحقق مما إذا كان نوع العنصر التابع لهذا الاستدلال يتطابق مع النوع المفترض. إذا كان T نوعًا ماديًا، فإن استدلال النوع يتحقق مما إذا كان النوع الديناميكي المحدد لـ a يتطابق مع T، هنا، إذا تم إجراء التحقق بنجاح، فإن استدلال النوع يعود بقيمة الديناميكية لـ a. وإلا، إذا فشل التحقق، فإن العملية ستعمل بشكل غير متوقع وتظهر استثناءً. إذا كان T نوعًا واجهة، فإن استدلال النوع يتحقق مما إذا كان النوع الديناميكي المحدد يتطابق مع T، هنا، إذا تم إجراء التحقق بنجاح، فإن استدلال النوع لا ينتج قيمة ديناميكية.

    //استدلال النوع 
    package main 
      
    import "fmt"
      
    func myfun(a interface{}) { 
      
        //استخراج قيمة a
        val := a.(string) 
        fmt.Println("قيمة: ", val) 
    } 
    func main() { 
      
        var val interface { 
        } = "w3codebox"
          
        myfun(val) 
    }

    الإخراج:

    القيمة: w3codebox

    في هذا المثال، إذا تم تعيينval := a.(string)جملة يُمكن تغييرها إلىval := a.(int)، فإن البرنامج سيشهد استثنائية panic. لذلك، لتجنب هذا المشكلة، نستخدم الجملة التالية:

    value, ok := a.(T)

    في هذا المكان، إذا كان نوع a يساوي T، فإن القيمة تحتوي على القيمة الديناميكية الخاصة بأ a، ويتم تعيين ok على true. وإذا لم يكن نوع a يساوي T، يتم تعيين ok على false ويحتوي value على القيمة الصفرية، ولا يُتوقع حدوث استثنائية panic. كما هو موضح في البرنامج التالي:

    package main
    import "fmt"
    func myfun(a interface{}) {
        value, ok := a.(float64)
        fmt.Println(value, ok)
    }
    func main() {
        var a1 interface {
        } = 98.09
        myfun(a1)
        var a2 interface {
        } = "w3codebox"
        myfun(a2)
    }

    الإخراج:

    98.09 نعم
    0 لا
  • التقييم النوعي:في واجهات Go، يتم استخدام التقييم النوعي لتحديد نوع المعلومات المحددة الخاصة بالواجهة مقارنة بأنواع متعددة في جملة case. يشبه هذا التقييم النوعي التقييم النوعي، ولكن هناك فرق، حيث يتم تحديد النوع باستخدام الحروف الكبيرة، وليس القيمة. يمكنك أيضًا مقارنة النوع بواجهة النوع.

    package main
    import "fmt"
    func myfun(a interface{}) {
        //استخدام التقييم النوعي
        switch a.(type) {
        case int:
            fmt.Println("النوع: int، القيمة: ", a.(int))
        case string:
            fmt.Println("\nالنوع: string، القيمة: ", a.(string))
        case float64:
            fmt.Println("\nالنوع: float64، القيمة: ", a.(float64))
        default:
            fmt.Println("\nلم يتم العثور على النوع")
        }
    }

    الإخراج:

    النوع: string، القيمة: w3codebox
    النوع: float64، القيمة: 67.9
    لم يتم العثور على النوع
  • استخدام واجهة:عندما تريد استخدام طريقة أو دالة لتوصيل أنواع مختلفة من المعلمات، يمكنك استخدام واجهة، مثل دالة Println(). أو، يمكنك أيضًا استخدام واجهة عندما يتم تنفيذ نفس واجهة بواسطة أنواع متعددة.