Golang接口赋值和方法集

比如《Go语言实战》中的一个例子:

// compile error
// cannot use u (type user) as type notifier in argument to sendNotification:
// user does not implement notifier (notify

package main

import "fmt"

type user struct {
    name  string
    email string
}
type notifier interface {
    notify()
}

func (u *user) notify() {
    fmt.Printf("sending user email to %s<%s>\n",
        u.name,
        u.email)
}
func sendNotification(n notifier) {
    n.notify()
}

func main() {
    u := user{
        name:  "stormzhu",
        email: "abc@qq.com",
    }
    sendNotification(u) 
}
// compile error
// cannot use u (type user) as type notifier in argument to sendNotification:
//  user does not implement notifier (notify method has pointer receiver)

如何判断类型是否实现了某个接口?

  1. 接口的定义
type iface struct {
    tab  *itab          // 类型信息
    data unsafe.Pointer //实际对象指针
}
type itab struct {
    inter *interfacetype // 接口类型
    _type *_type         // 实际对象类型
    fun   [1]uintptr     // 实际对象方法地址
}

对一个接口赋值的时候,会拷贝类型信息和该类型的方法集。只要这个类型的方法集中包括这个接口的所有方法,那么它就是实现了这个接口,才能够赋值给这个接口。

  1. 方法集
  • 类型T的方法集包含所有 receiver T方法。
  • 类型*T的方法集包含所有 receiver T + *T方法。
  • 匿名嵌入S,类型T的方法集包含所有 receiver T + S方法。
  • 匿名嵌入*S,类型T的方法集包含所有 receiver T + S + *S方法。
  • 匿名嵌入S*S,类型*T的方法集包含所有 receiver T + *T + S + *S方法。

总结:

  1. T*T不是一个类型,他们的方法集不同
  2. 类型*T的方法集包含所有 receiver T + *T方法,类型T的方法集只包含所有 receiver T方法。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。