Поиск…


замечания

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

Структуры

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

package main

type User struct {
    ID uint64
    FullName string
    Email    string
}

func main() {
    user := User{
        1,
        "Zelalem Mekonen",
        "zola.mk.27@gmail.com",
    }

    fmt.Println(user) // {1 Zelalem Mekonen zola.mk.27@gmail.com}
}

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

type User struct {
    ID uint64
    FullName, Email string
}

user := new(User)

user.ID = 1
user.FullName = "Zelalem Mekonen"
user.Email = "zola.mk.27@gmail.com"

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

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

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",
        "zola.mk.27@gmail.com",
        admin,
    }

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

    fmt.Println(user) // {1 Zelalem Mekonen zola.mk.27@gmail.com {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",
        "zola.mk.27@gmail.com",
        admin,
    }

    user.SendEmail("Hello") // Email sent to: zola.mk.27@gmail.com

    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",
        "zola.mk.27@gmail.com",
    }

    user.SendEmail("Hello") // Sent email to: zola.mk.27@gmail.com

    user.ChangeEmail("zola@gmail.com")

    fmt.Println(user.Email) // zola@gmail.com
}

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

Интерфейсы обеспечивают способ указания поведения объекта, если что-то может это сделать, тогда он может быть использован здесь. интерфейс определяет набор методов, но эти методы не содержат кода, поскольку они являются абстрактными или имплементация предоставляется пользователю интерфейса. в отличие от большинства интерфейсов с объектно-ориентированными языками могут содержать переменные в 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",
        "zola.mk.27@gmail.com",
    }

    RunnerExample(admin)

    RunnerExample(user)
    
}


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow