go和python中的鸭子类型--Duck Typing

鸭子类型(duck typing):是动态类型的一种风格,不管对象属于哪个,也不管声明的具体接口是什么,只要对象实现了相应的方法,函数就可以在对象上执行操作.
即忽略对象的真正类型,转而关注对象有没有实现所需的方法、签名和语义.

在这里插入图片描述
图片中的大黄鸭,它是不是一只鸭子呢?

这个问题,得看你从哪个角度去看,如果从人们常识的认知中的角度去看,它显然不是一只鸭子,因为它连最基本的生命都没有。

但是从 Duck Typing 的角度来看,它就是一只鸭子!

鸭子类型这一名字出自James Whitcomb Riley在鸭子测试中提出的如下的表述:

当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被
称为鸭子。
Python 中的 Duck Typing

先看一个函数:

def down(fetcher):
	return fetcher.get("http://xxx");

有一个 down 函数,传过来一个 fetcher 参数,fetcher 是可以获取一个 url 链接的资源的。
这个 fetcher 就是一个 Duck Typing 的对象,使用者约定好这个 fetcher 会有一个 get 函数就可以了。

显然这个 down 函数会有以下问题:

运行时才知道传入的 fetcher 有没有 get 函数。那么站在 download 函数的使用者的角度上看,我怎么知道需要给 fetcher 实现 get 方法呢?实际情况中,可能 down 函数的代码很长,可能 fetcher 不只要实现 get 方法,还有其它方法需要实现。通常这种情况需要通过加注释来说明。

Go 中的 Duck Typing

如果 fetcher 参数需要同时实现两个或以上的接口方法时,实现如下

type Fetcher interface {
   	Get(url string) string
}

type Saver interface {
   	Save(content string)
}

type FetcherAndSaver interface {
    Fetcher
    Saver
}

func down(f Fetcher) string {  // Fetcher 接口的down方法
    return f.Get("http://xxx")
}

func save(f Saver) {   // Saver 接口的save方法
    f.Save("some thing")
}

func downAndSave(f FetcherAndSaver) {
    content := f.Get("http://xxxx")
    f.Save(content)
}

// 实现者
type MyFetcherAndSaver struct {

}

func (f MyFetcherAndSaver) Get(url string) string {
    ...
}

func (f MyFetcherAndSaver) Save(content string) {
    ...
}

func main() {
    f := MyFetcherAndSaver{}
    down(f)
    save(f)
    downAndSave(f)
}

这里定义了三个接口,只要有 Get 方法的就是 Fetcher,只要有 Save 方法的就是 Saver,同时有 Get 方法和 Save 方法就是 FetcherAndSaver 。

实现者 MyFetcherAndSaver 并不需要声明它实现了哪些接口,只要它有相关接口的所定义的方法,那么它的实例,就即能作为 Fetcher 接口来使用,又能作为 Saver 接口来使用,也能作为 FetcherAndSaver 接口来使用。

Go 的实现方法相对比较灵活,又不失类型检查。总的来说,特点有:

(1) 能同时实现多个接口
(2) 和python相比 , go 中的 Duck Typing 更加灵活
(3) fetcher 有没有 get 方法,python 是运行时才知道,go 是编译时就知道

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值