Suche…


Bemerkungen

Die Schnittstelle kann nicht mit Zeigerempfängern implementiert werden, da *User kein User

Structs

Go unterstützt benutzerdefinierte Typen in Form von Strukturen und Typ-Aliasnamen. structs sind zusammengesetzte Typen, die Komponententeile, aus denen der Strukturtyp besteht, werden Felder genannt . Ein Feld hat einen Typ und einen Namen, die einmalig sein müssen.

package main

type User struct {
    ID uint64
    FullName string
    Email    string
}

func main() {
    user := User{
        1,
        "Zelalem Mekonen",
        "[email protected]",
    }

    fmt.Println(user) // {1 Zelalem Mekonen [email protected]}
}

Dies ist auch eine gesetzliche Syntax zur Definition von Strukturen

type User struct {
    ID uint64
    FullName, Email string
}

user := new(User)

user.ID = 1
user.FullName = "Zelalem Mekonen"
user.Email = "[email protected]"

Eingebettete Strukturen

Da eine Struktur auch ein Datentyp ist, kann sie als anonymes Feld verwendet werden. Die äußere Struktur kann direkt auf die Felder der eingebetteten Struktur zugreifen, selbst wenn die Struktur aus einem anderen Paket stammt. Dieses Verhalten bietet eine Möglichkeit, einige oder alle Ihrer Implementierung von einem anderen Typ oder einer Gruppe von Typen abzuleiten.

package main

type Admin struct {
    Username, Password string
}

type User struct {
    ID uint64
    FullName, Email string
    Admin // embedded struct
}

func main() {
    admin := Admin{
        "zola",
        "supersecretpassword",
    }

    user := User{
        1,
        "Zelalem Mekonen",
        "[email protected]",
        admin,
    }

    fmt.Println(admin) // {zola supersecretpassword}

    fmt.Println(user) // {1 Zelalem Mekonen [email protected] {zola supersecretpassword}}

    fmt.Println(user.Username) // zola

    fmt.Println(user.Password) // supersecretpassword
}

Methoden

In Go ist eine Methode

eine Funktion, die auf eine Variable eines bestimmten Typs wirkt, der als Empfänger bezeichnet wird

Der Empfänger kann alles sein, nicht nur structs sondern sogar eine function . Alias-Typen für integrierte Typen wie int , string und bool können eine Methode haben. Eine Ausnahme von dieser Regel besteht darin, dass interfaces ( structs ) keine Methoden haben können, da eine Schnittstelle ist eine abstrakte Definition und eine Methode ist eine Implementierung, bei der versucht wird, einen Kompilierungsfehler zu generieren.

Durch das Kombinieren von structs und methods Sie eine genaue Entsprechung einer class in der objektorientierten Programmierung.

Eine Methode in Go hat die folgende Signatur

func (name receiverType) methodName(paramterList) (returnList) {}

package main

type Admin struct {
    Username, Password string
}

func (admin Admin) Delete() {
    fmt.Println("Admin Deleted")
}

type User struct {
    ID uint64
    FullName, Email string
    Admin
}

func (user User) SendEmail(email string) {
    fmt.Printf("Email sent to: %s\n", user.Email)
} 

func main() {
    admin := Admin{
        "zola",
        "supersecretpassword",
    }

    user := User{
        1,
        "Zelalem Mekonen",
        "[email protected]",
        admin,
    }

    user.SendEmail("Hello") // Email sent to: [email protected]

    admin.Delete() // Admin Deleted
}

Pointer Vs Wertempfänger

Der Empfänger einer Methode ist aus Leistungsgründen normalerweise ein Zeiger, da wir keine Kopie der Instanz erstellen würden, wie dies beim Wertempfänger der Fall wäre. Dies gilt insbesondere, wenn der Empfängertyp eine Struktur ist. Ein anderer Grund, aus dem Empfängertyp einen Zeiger zu machen, wäre so, dass wir die Daten ändern könnten, auf die der Empfänger zeigt.

Ein Wertempfänger wird verwendet, um eine Änderung der Daten zu vermeiden, die der Empfänger enthält. Ein vaule-Empfänger kann einen Performance-Treffer verursachen, wenn der Empfänger eine große Struktur hat.

package main

type User struct {
    ID uint64
    FullName, Email string
}

// We do no require any special syntax to access field because receiver is a pointer
func (user *User) SendEmail(email string) {
    fmt.Printf("Sent email to: %s\n", user.Email)
}    

// ChangeMail will modify the users email because the receiver type is a ponter
func (user *User) ChangeEmail(email string) {
    user.Email = email;
}

func main() {
    user := User{
        1,
        "Zelalem Mekonen",
        "[email protected]",
    }

    user.SendEmail("Hello") // Sent email to: [email protected]

    user.ChangeEmail("[email protected]")

    fmt.Println(user.Email) // [email protected]
}

Schnittstelle & Polymorphismus

Schnittstellen bieten eine Möglichkeit, das Verhalten eines Objekts anzugeben. Wenn dies möglich ist, kann es hier verwendet werden. Eine Schnittstelle definiert eine Reihe von Methoden. Diese Methoden enthalten jedoch keinen Code, da sie abstrakt sind oder die Implementierung dem Benutzer der Schnittstelle überlassen wird. Im Gegensatz zu den meisten objektorientierten Sprachen können Schnittstellen in Go Variablen enthalten.

Polymorphismus ist die Essenz der objektorientierten Programmierung: Die Fähigkeit, Objekte unterschiedlichen Typs einheitlich zu behandeln, solange sie an derselben Schnittstelle haften. Go-Schnittstellen bieten diese Funktion auf eine direkte und intuitive Weise

package main

type Runner interface {
    Run()
}

type Admin struct {
    Username, Password string
}

func (admin Admin) Run() {
    fmt.Println("Admin ==> Run()");
}

type User struct {
    ID uint64
    FullName, Email string
}

func (user User) Run() {
    fmt.Println("User ==> Run()")
}

// RunnerExample takes any type that fullfils the Runner interface
func RunnerExample(r Runner) {
    r.Run()
}

func main() {
    admin := Admin{
        "zola",
        "supersecretpassword",
    }

    user := User{
        1,
        "Zelalem Mekonen",
        "[email protected]",
    }

    RunnerExample(admin)

    RunnerExample(user)
    
}


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow