返回Golang中的接口



假设我们想在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!中的字符串。

如何处理此问题?

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

  1. 如果操作数实现错误接口,将调用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

Go在打印时以不同方式处理实现errortype。您的接口ResponseError不通过添加Error() string来实现error

要可视化我所说的内容,请参阅以下使用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: %sn", user.NewOK())
fmt.Printf("Using %%v: %vn", user.NewOK())
fmt.Printf("Using %%v and call function ErrorMsg: %vn", user.NewOK().ErrorMsg())
fmt.Printf("Using %%s and call function ErrorMsg: %sn", 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: %sn", user.NewOK())
fmt.Printf("Using %%v: %vn", user.NewOK())
fmt.Printf("Using %%v and call function ErrorMsg: %vn", user.NewOK().ErrorMsg())
fmt.Printf("Using %%s and call function ErrorMsg: %sn", 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!

最新更新