Sök…


Anmärkningar

Gränssnittet kan inte implementeras med pekmottagare eftersom *User är inte User

structs

Go stöder användardefinierade typer i form av strukturer och typalias. strukturer är sammansatta typer, de komponentuppgifter som utgör strukturtypen kallas fält . ett fält har en typ och ett namn som måste vara ungefär.

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]}
}

detta är också en juridisk syntax för att definiera strukturer

type User struct {
    ID uint64
    FullName, Email string
}

user := new(User)

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

Inbyggda strukturer

eftersom en struktur också är en datatyp, kan den användas som ett anonymt fält, den yttre strukturen kan direkt komma åt fälten för den inbäddade strukturen även om strukturen kom från ett annat paket. detta beteende ger ett sätt att härleda en del av eller hela din implementering från en annan typ eller en uppsättning typer.

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
}

metoder

I Go är en metod

en funktion som verkar på en variabel av en viss typ, kallad mottagaren

mottagaren kan vara vad som helst, inte bara structs utan även en function , aliastyper för inbyggda typer som int , string , bool kan ha en metod, ett undantag från denna regel är att interfaces (diskuteras senare) inte kan ha metoder, eftersom en gränssnitt är en abstrakt definition och en metod är en implementering, försöker det generera ett sammanställningsfel.

genom att kombinera structs och methods du få en nära ekvivalent av en class i objektorienterad programmering.

en metod i Go har följande 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 Value-mottagare

mottagaren av en metod är vanligtvis en pekare av prestandaskäl eftersom vi inte skulle göra en kopia av instansen, som det skulle vara fallet i värdemottagaren, detta är särskilt sant om mottagartypen är en struktur. ett annat skäl att göra mottagartypen till en pekare skulle vara så vi kan ändra de data mottagaren pekar på.

en värdemottagare används för att undvika modifiering av data som mottagaren innehåller, en vaule-mottagare kan orsaka en prestationshit om mottagaren är en stor struktur.

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]
}

Gränssnitt och polymorfism

Gränssnitt ger ett sätt att specificera ett objekts beteende, om något kan göra detta kan det användas här. ett gränssnitt definierar en uppsättning metoder, men dessa metoder innehåller inte kod eftersom de är abstrakta eller genomförandet lämnas till användaren av gränssnittet. till skillnad från de flesta objektorienterade språk kan gränssnitt innehålla variabler i Go.

Polymorfism är kärnan i objektorienterad programmering: förmågan att behandla objekt av olika typer enhetligt så länge de följer samma gränssnitt. Go-gränssnitt ger denna kapacitet på ett mycket direkt och intuitivt sätt

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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow