10

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

 4 years ago
source link: https://studygolang.com/articles/25786
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

对于 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","[email protected]","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 类型的指针的方法集既包含值接收者声明的方法,也包含指针接收者声明的方法. 也就是说 如果方法集使用的是指针类型,那么我们必须传入指针类型的值,如果方法集使用的是指类型,那么我们既可以传入值类型也可以传入指针类型

期待一起交流

iqq26vf.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK