Возвращение интерфейса в Голанге - PullRequest
0 голосов
/ 24 ноября 2018

Допустим, мы хотим расширить функцию Error() на интерфейсе error.Мы можем просто создать структуру, полученную из строки, реализующей метод Error().Например:

type NewUser struct {
    Email           string
    Password        string
}
type ErrMissingField string

func (e ErrMissingField) Error() string {
    return string(e) + " is required"
}

func (u *NewUser) OK() error {
    if len(u.Email) == 0 {
        return ErrMissingField("email")
    }
    if len(u.Password) == 0 {
        return ErrMissingField("password")
    }
    return nil
}

Приведенный выше код вернет либо email is required, либо password is required.

Но, если я создам свой собственный интерфейс, скажем, ResponseError, например так:

type ResponseError interface {
    ErrorMsg() string
}

type CustomErr string

func (c CustomErr) ErrorMsg() string {
    return "[Error] " + string(c)
}
func (u *NewUser) NewOK() ResponseError {
    if len(u.Email) == 0 {
        return CustomErr("Email required!")
    }
    if len(u.Password) == 0 {
        return CustomErr("Password Required!")
    }
    return nil
}

Он не напечатает реализацию метода, которую я написал с [Error].Он просто печатает строку, которую я передал в структуру Email required! или Password Required!.

Как с этим работать?

Ответы [ 2 ]

0 голосов
/ 24 ноября 2018

Go обрабатывает type s, которые реализуют error по-разному при печати.Ваш интерфейс ResponseError не не реализует error путем добавления Error() string.

Чтобы увидеть, о чем я говорю, посмотрите следующий пример с использованием интерфейса error:

type NewUser struct {
    Email    string
    Password string
}

type ResponseError interface {
    error
    ErrorMsg() string
}

type CustomErr string

func (c CustomErr) ErrorMsg() string {
    return "[Error] " + string(c)
}

func (c CustomErr) Error() string {
    return c.ErrorMsg()
}

func (u *NewUser) NewOK() ResponseError {
    if len(u.Email) == 0 {
        return CustomErr("Email required!")
    }
    if len(u.Password) == 0 {
        return CustomErr("Password Required!")
    }
    return nil
}

func main() {
    user := NewUser{}
    fmt.Printf("Using %%s: %s\n", user.NewOK())
    fmt.Printf("Using %%v: %v\n", user.NewOK())
    fmt.Printf("Using %%v and call function ErrorMsg: %v\n", user.NewOK().ErrorMsg())
    fmt.Printf("Using %%s and call function ErrorMsg: %s\n", user.NewOK().ErrorMsg())
}

Будет напечатано следующее:

Using %s: [Error] Email required!
Using %v: [Error] Email required!
Using %v and call function ErrorMsg: [Error] Email required!
Using %s and call function ErrorMsg: [Error] Email required!

Однако без интерфейса error:

type NewUser struct {
    Email    string
    Password string
}

type ResponseError interface {
    ErrorMsg() string
}

type CustomErr string

func (c CustomErr) ErrorMsg() string {
    return "[Error] " + string(c)
}


func (u *NewUser) NewOK() ResponseError {
    if len(u.Email) == 0 {
        return CustomErr("Email required!")
    }
    if len(u.Password) == 0 {
        return CustomErr("Password Required!")
    }
    return nil
}

func main() {
    user := NewUser{}
    fmt.Printf("Using %%s: %s\n", user.NewOK())
    fmt.Printf("Using %%v: %v\n", user.NewOK())
    fmt.Printf("Using %%v and call function ErrorMsg: %v\n", user.NewOK().ErrorMsg())
    fmt.Printf("Using %%s and call function ErrorMsg: %s\n", user.NewOK().ErrorMsg())
}

Вывод:

Using %s: Email required!
Using %v: Email required!
Using %v and call function ErrorMsg: [Error] Email required!
Using %s and call function ErrorMsg: [Error] Email required!
0 голосов
/ 24 ноября 2018

Если вы используете fmt для печати, то из https://golang.org/pkg/fmt

Если операнд реализует интерфейс ошибки, будет вызван метод Error для преобразования объекта в строку, которая затем будет отформатирована в соответствии с требованиями глагола (если есть).

Если операнд реализует метод String () string, этот метод будет вызван для преобразования объекта в строку, которая затем будет отформатирована в соответствии с требованиями глагола (если есть)

Вот почему при реализации интерфейса Ошибка он печатается с помощью функции Error().Если вы хотите настраиваемый вывод для другого интерфейса, например ResponseError, реализуйте метод String().

package main

import (
    "fmt"
)

type NewUser struct {
    Email           string
    Password        string
}

type ResponseError interface {
    ErrMsg()
    String() string
}

type CustomErr string

func (c CustomErr) String() string {
    return "[Error] " + string(c)
}

func (c CustomErr) ErrMsg() {}

func (u *NewUser) NewOK() ResponseError {
    if len(u.Email) == 0 {
        return CustomErr("Email required!")
    }
    if len(u.Password) == 0 {
        return CustomErr("Password Required!")
    }
    return nil
}

func main() {
    u := &NewUser{}
    fmt.Println(u.NewOK())
}

Go Playground: https://play.golang.org/p/khAAtLodEND

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