Поиск…


замечания

Интерфейс не может быть реализован с помощью приемников указателей, потому что *User не является User

Структуры

Go поддерживает определенные пользователем типы в виде структур и псевдонимов типов. structs являются составными типами, компоненты частей данных, которые составляют тип структуры, называются полями . поле имеет тип и имя, которое должно быть unqiue.

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

это также юридический синтаксис для определения структур

type User struct {
    ID uint64
    FullName, Email string
}

user := new(User)

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

Встроенные структуры

потому что структура также является типом данных, она может использоваться как анонимное поле, внешняя структура может напрямую обращаться к полям встроенной структуры, даже если структура получена из разного пакета. это поведение обеспечивает способ получения некоторой или всей вашей реализации из другого типа или набора типов.

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
}

методы

В методе Go метод

функция, действующая на переменную определенного типа, называемую приемником

приемник может быть чем угодно, не только structs но даже function , типы псевдонимов для встроенных типов, такие как int , string , bool могут иметь метод, исключение из этого правила заключается в том, что interfaces (обсужденные позже) не могут иметь методы, интерфейс - это абстрактное определение, а метод - реализация, которая пытается сгенерировать ошибку компиляции.

комбинируя structs и methods вы можете получить близкий эквивалент class в объектно-ориентированном программировании.

метод в Go имеет следующую подпись

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
}

Указатель Vs Приемник значения

приемник метода обычно является указателем на производительность, потому что мы не будем копировать экземпляр, как это было бы в случае приемника значений, это особенно верно, если тип приемника является структурой. причина анотера, чтобы сделать тип приемника указателем, чтобы мы могли изменить данные, на которые указывает приемник.

приемник значений используется, чтобы избежать изменения данных, содержащихся в приемнике, приемник ваулей может привести к потере производительности, если приемник является большой структурой.

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

Интерфейс и полиморфизм

Интерфейсы обеспечивают способ указания поведения объекта, если что-то может это сделать, тогда он может быть использован здесь. интерфейс определяет набор методов, но эти методы не содержат кода, поскольку они являются абстрактными или имплементация предоставляется пользователю интерфейса. в отличие от большинства интерфейсов с объектно-ориентированными языками могут содержать переменные в Go.

Полиморфизм - это суть объектно-ориентированного программирования: способность равномерно обрабатывать объекты разных типов, если они придерживаются одного и того же интерфейса. Интерфейсы Go обеспечивают эту возможность очень простым и интуитивно понятным способом

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
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow