Go的接口与多态

什么是Go的接口?

接口可以说是一种类型,可以粗略的理解为他的变量是一堆方法。

一个简单的案例:

 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()
 }

 

那么在r.Body中会有如下架构:

 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()
 }

 

上述代码出自《Go语言实战》

posted @ 2022-09-23 18:32  bighu  阅读(135)  评论(0编辑  收藏  举报