Go学习笔记-接口(interface)的实现

对于 go 的接口,我们先来看看官方的解释

接口是用来定义行为的类型。这些被定义的行为不由接口直接实现,而是通过方法由用户定义的类型实现。如果用户定义的类型实现了某个接口类型声明的一组方法,那么这个用户定义的类型的值就可以赋给这个接口类型的值。这个赋值会把用户定义的类型的值存入接口类型的值

也就是说接口定义的方法,需要由具体的类型去实现它。

下面我们来看看接口的实现

在go语言中,接口的实现与 struct 的继承一样,不需要通过某个关键字 php:implements 来声明。在 go 中一个类只要实现了某个接口要求的所有方法,我们就说这个类实现了该接口。下面来看一个例子

type NoticeInterface interface {  
   seedEmail()  
   seedSMS()  
}  
  
type Student struct {  
   Name string  
  Email string  
  Phone string  
}  
  
func (Student *Student)seedEmail()  {  
   fmt.Printf("seedEmail to %s\r\n",Student.Email)  
}  
  
func (Student *Student)seedSMS()  {  
   fmt.Printf("seedSMS to %s\r\n",Student.Email)  
}

这里我们就说 student 实现了 NoticeInterface 接口。下面来看看接口的调用是否成功

func main()  {  
   student := Student{"andy","jiumengfadian@live.com","10086"}  
   //seedNotice(student)  //这里会产生一个错误
   seedNotice(&student)  
}  
  
//创建一个seedNotice方法,需要接受一个实现了`NoticeInterface`类型  
func seedNotice(notice NoticeInterface)  {  
   notice.seedEmail()  
   notice.seedSMS()  
}

在上面的例子中,我们创建了一个 seedNotice 需要接受一个实现了 NoticeInterface 的类型。但是我在 main 中第一个调用该方法的时候,传入了一个 student 值。这个时候会产生一个错误

.\main.go:26:12: cannot use student (type Student) as type NoticeInterface in argument to seedNotice:
    Student does not implement NoticeInterface (seedEmail method has pointer receiver)

意思是 student 没有实现 NoticeInterface 不能作为 NoticeInterface 的类型参数。为什么会有这样的错误呢?我们在来看看上面的

func (Student *Student)seedEmail()  {  
   fmt.Printf("seedEmail to %s\r\n",Student.Email)  
}  
  
func (Student *Student)seedSMS()  {  
   fmt.Printf("seedSMS to %s\r\n",Student.Email)  
}

这里我们对 seedEmail,seedSMS 的实现都是对于 *Student 也就是 student 的地址类型的,

所以我们这也就必须传入一个 student 的指针 seedNotice(&student)

这里给出一个规范中的方法集描述

method receivers values
(t T) T and *T
(t *T) t *T

描述中说到,T 类型的值的方法集只包含值接收者声明的方法。而指向 T 类型的指针的方法集既包含值接收者声明的方法,也包含指针接收者声明的方法. 也就是说 如果方法集使用的是指针类型,那么我们必须传入指针类型的值,如果方法集使用的是指类型,那么我们既可以传入值类型也可以传入指针类型

期待一起交流