Golang返回接口

时间:2018-11-24 08:03:38

标签: go methods interface

假设我们要在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 requiredpassword 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 :(得分:3)

如果您使用fmt打印,则从https://golang.org/pkg/fmt

  1. 如果操作数实现了error接口,则将调用Error方法将对象转换为字符串,然后根据动词的要求对其进行格式化(如果有)。

  2. 如果操作数实现String()字符串方法,则该方法将被调用以将对象转换为字符串,然后将根据动词(如果有)的要求对其进行格式化

这就是为什么当您实现 Error 接口时,它会通过调用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())
}

去游乐场:https://play.golang.org/p/khAAtLodEND

答案 1 :(得分:1)

Go在打印时对待实现type的{​​{1}}有所不同。您的界面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())
}