接口可以说是一种类型,可以粗略的理解为他的变量是一堆方法。
一个简单的案例:
r,_ := http.Get("http://www.baidu.com") io.copy(os.Stdout,r.Body)
其中 io.copy 接受的变量是 io.Writer,io.Reader(实际上是接口类型)
而os.Stdout 和 r.Body 并不是这两种类型,但是他们实现了这两个接口,所以编译器可以识别出这是可行的的。
而 go 是怎么实现接口的呢?
可以假设 io.Reader 是这么写的:
type Reader interface{ funca() funcb() funcc() }
type Body struct{ ... } func (b Body)funca(){ ... } func (b Body)funcb(){ ... } func (b Body)funcc(){ ... }
在go中无需声明要实现什么接口,你只需要实现这个接口的所有方法就是直接显现了这个接口,也就是没有显示的实现接口的这一说法。
这里有一个有意思的地方。
很明显 结构体A 与结构体A 的指针是不同的类型
但 结构体A实现的方法对 A的指针有效,A的指针实现的方法对A无效
package main import "fmt" // duration是一个基于int类型的类型 type duration int // 使用更可读的方式格式化duration值 func (d *duration) pretty() string { return fmt.Sprintf("Duration: %d", *d) } // main是应用程序的入口 func main() { duration(42).pretty() // ./listing46.go:17: 不能通过指针调用duration(42)的方法 // ./listing46.go:17: 不能获取duration(42)的地址 }
多态
go利用接口实现多态的方式 简单粗暴
不同类型实现的同一接口,在接口调用时就会完美的体现出来
// 这个示例程序使用接口展示多态行为 package main import ( "fmt" ) // notifier是一个定义了 // 通知类行为的接口 type notifier interface { notify() } // user在程序里定义一个用户类型 type user struct { name string email string } // notify使用指针接收者实现了notifier接口 func (u *user) notify() { fmt.Printf("Sending user email to %s<%s>\n", u.name, u.email) } // admin定义了程序里的管理员 type admin struct { name string email string } // notify使用指针接收者实现了notifier接口 func (a *admin) notify() { fmt.Printf("Sending admin email to %s<%s>\n", a.name, a.email) } // main是应用程序的入口 func main() { // 创建一个user值并传给sendNotification bill := user{"Bill", "bill@email.com"} sendNotification(&bill) // 创建一个admin值并传给sendNotification lisa := admin{"Lisa", "lisa@email.com"} sendNotification(&lisa) } // sendNotification接受一个实现了notifier接口的值 // 并发送通知 func sendNotification(n notifier) { n.notify() }
原文地址:https://www.cnblogs.com/blogforeverything/p/16723878.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。