对于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 类型的指针的方法集既包含值接收者声明的方法,也包含指针接收者声明的方法. 也就是说 如果方法集使用的是指针类型,那么我们必须传入指针类型的值,如果方法集使用的是指类型,那么我们既可以传入值类型也可以传入指针类型
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。