Go接口继承

Go interface inheritance

我是 Go 的新手,一件事不明白。让我们使用一个有效的代码:

package main

import "fmt"

type User struct {
    Name  string
    Email string
}

type Admin struct {
    User
    Level string
}

type Notifier interface {
    notify()
}

func (u *User) notify() {
    fmt.Println("Notified", u.Name)
}

func SendNotification(notify Notifier) {
    notify.notify()
}

func main() {
    admin := Admin{
        User: User{
            Name:  "john smith",
            Email: "john@email.com",
        },
        Level: "super",
    }

    SendNotification(&admin)
    admin.User.notify()
    admin.notify()
}

此处函数 SendNotification 将管理结构识别为 Notifier,因为管理结构可以访问通过指针接收器实现接口的嵌入式用户结构.行。 为什么下面的代码不起作用。为什么 norgateMathError 需要实现接口而不是使用 err error 的实现(对我来说也是一样的情况):

package main

import (
    "fmt"
    "log"
)

type norgateMathError struct {
    lat  string
    long string
    err  error
}

// func (n norgateMathError) Error() string {
//  return fmt.Sprintf("a norgate math error occured: %v %v %v", n.lat, n.long, n.err)
// }

func main() {
    _, err := sqrt(-10.23)
    if err != nil {
        log.Println(err)
    }
}

func sqrt(f float64) (float64, error) {
    if f < 0 {
        nme := fmt.Errorf("norgate math redux: square root of negative number: %v", f)
        return 0, &norgateMathError{"50.2289 N", "99.4656 W", nme}
    }
    return 42, nil
}
.\custom_error.go:28:13: cannot use &norgateMathError{...} (type *norgateMathError) as type error in return argument:
        *norgateMathError does not implement error (missing Error method)

在第一种情况下 User 嵌入Admin 中,因此 Admin 可以访问 [=11] 上定义的所有方法=]类型。

在第二种情况下,norgateMathError 类型 Error 的字段 err,因此不会自动获得对其方法的访问权限.

如果您希望 norgateMathError 有一个 Error() 方法,您必须手动定义它

func (n norgateMathError) Error() string {
  return n.err.Error()
}

嵌入字段和仅拥有字段是有区别的。可以在 reference

中找到更多信息