1

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

短腿子猿


旧梦发癫
678 声望76 粉丝

PHP、Golang