编程语言中的 DUCK TYPING|python、c++、java、go

2023-10-30 20:52

本文主要是介绍编程语言中的 DUCK TYPING|python、c++、java、go,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

如果一只动物走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只动物就可以被称为鸭子。

许多编程语言都支持 Duck Typing ,通常 Duck Typing 是动态编程语言用来实现多态的一种方式。

在理解 Duck Typing 前,先看一张图片,这是曾经一度很火的大黄鸭

在这里插入图片描述

先问一个比较考三观的问题:图片中的大黄鸭,它是不是一只鸭子呢?

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

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

Duck Typing 的原话是,走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么它就是一只鸭子。

这个原话是可以灵活理解的,就看我们怎么定义鸭子的行为,我们可以说,能浮在水上游的,黄色的,可爱的就是鸭子,那么,图片中的大黄鸭,它就是一只鸭子!

这就是所谓的 Duck Typing,它只关心事物的外部行为而非内部结构。它并不关心你这只鸭子是长肉的还是充气的。

在编程中,也常常用这种方式来描述事物。那么不同的编程语言中,Duck Typing 是怎么样实现的呢?

1. Python 中的 Duck Typing

先看一个函数:

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

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

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

2. C++ 中的 Duck Typing

C++ 不是动态语言,但是它也能支持 Duck Typing,它是通过模板来支持的。
示例代码:

template <class F>
string download(const F& fetcher){return fetcher.get("http://xxxx")
}

这段代码与 Python 的实现方法类似,这个 fetcher 随便什么类型都可以,只要实现一个 get 方法,就能通过编译。
那么这种实现方法有什么缺点呢,就是,编译时,才知道传入的 fetcher 有没有 get 方法。
但它比 python 好一点了,python 是运行时才知道,C++ 是编译时就知道。
同样,这种情况,还是需要注释来说明。

3. Java 中的类似代码

Java 没有 Duck Typing,它只有类似的代码。Java 的 duck typing :

<F extends FetcherInterface>
String download(F fetcher){return fetcher.get("http://xxxx")
}

它同样也用了模板类型。模板 F 必须 extends FetcherInterface ,有了这个限定,就能逼着 download 函数的使用者对 fetcher 实现 get 方法,它解决了需要注释来说明的缺点。
传入的参数必须实现 FetcherInterface 接口,就没有运行时发现错误,编译时发现错误的问题。
但是,它严格上来说不是 Duck Typing 。

如果 download 函数只依赖 fetcher 的 get 方法,而 FetcherInterface 接口必须要实现除 get 方法以外,还有其它方法,那么也要一一实现,非常不灵活。

4. Go 中的 Duck Typing

在 Java 的 Duck Typing 类似代码中,如果 fetcher 参数需要同时实现两个或以上的接口方法时,Java 是没有办法做到的。但 Go 语言可以做到。

type Fetcher interface {Get(url string) string
}type Saver interface {Save(content string)
}type FetcherAndSaver interface {FetcherSaver
}func download(f Fetcher) string {return f.Get("http://xxxx")
}func save(f saver) {f.Save("some thing")
}func downloadAndSave(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{}download(f)save(f)downloadAndSave(f)
}

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

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

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

  1. 即能同时实现多个接口
  2. 又具有 python , C++ 的 Duck Typing 灵活性
  3. 又具有 java 的类型检查。

转载来源:
https://segmentfault.com/a/1190000019607240

这篇关于编程语言中的 DUCK TYPING|python、c++、java、go的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/310534

相关文章

java对接海康摄像头的完整步骤记录

《java对接海康摄像头的完整步骤记录》在Java中调用海康威视摄像头通常需要使用海康威视提供的SDK,下面这篇文章主要给大家介绍了关于java对接海康摄像头的完整步骤,文中通过代码介绍的非常详细,需... 目录一、开发环境准备二、实现Java调用设备接口(一)加载动态链接库(二)结构体、接口重定义1.类型

SpringBoot读取ZooKeeper(ZK)属性的方法实现

《SpringBoot读取ZooKeeper(ZK)属性的方法实现》本文主要介绍了SpringBoot读取ZooKeeper(ZK)属性的方法实现,强调使用@ConfigurationProperti... 目录1. 在配置文件中定义 ZK 属性application.propertiesapplicati

Java Multimap实现类与操作的具体示例

《JavaMultimap实现类与操作的具体示例》Multimap出现在Google的Guava库中,它为Java提供了更加灵活的集合操作,:本文主要介绍JavaMultimap实现类与操作的... 目录一、Multimap 概述Multimap 主要特点:二、Multimap 实现类1. ListMult

Java中常见队列举例详解(非线程安全)

《Java中常见队列举例详解(非线程安全)》队列用于模拟队列这种数据结构,队列通常是指先进先出的容器,:本文主要介绍Java中常见队列(非线程安全)的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一.队列定义 二.常见接口 三.常见实现类3.1 ArrayDeque3.1.1 实现原理3.1.2

SpringBoot整合Apache Flink的详细指南

《SpringBoot整合ApacheFlink的详细指南》这篇文章主要为大家详细介绍了SpringBoot整合ApacheFlink的详细过程,涵盖环境准备,依赖配置,代码实现及运行步骤,感兴趣的... 目录1. 背景与目标2. 环境准备2.1 开发工具2.2 技术版本3. 创建 Spring Boot

springboot加载不到nacos配置中心的配置问题处理

《springboot加载不到nacos配置中心的配置问题处理》:本文主要介绍springboot加载不到nacos配置中心的配置问题处理,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录springboot加载不到nacos配置中心的配置两种可能Spring Boot 版本Nacos

Java反射实现多属性去重与分组功能

《Java反射实现多属性去重与分组功能》在Java开发中,​​List是一种非常常用的数据结构,通常我们会遇到这样的问题:如何处理​​List​​​中的相同字段?无论是去重还是分组,合理的操作可以提高... 目录一、开发环境与基础组件准备1.环境配置:2. 代码结构说明:二、基础反射工具:BeanUtils

Python远程控制MySQL的完整指南

《Python远程控制MySQL的完整指南》MySQL是最流行的关系型数据库之一,Python通过多种方式可以与MySQL进行交互,下面小编就为大家详细介绍一下Python操作MySQL的常用方法和最... 目录1. 准备工作2. 连接mysql数据库使用mysql-connector使用PyMySQL3.

使用Python实现base64字符串与图片互转的详细步骤

《使用Python实现base64字符串与图片互转的详细步骤》要将一个Base64编码的字符串转换为图片文件并保存下来,可以使用Python的base64模块来实现,这一过程包括解码Base64字符串... 目录1. 图片编码为 Base64 字符串2. Base64 字符串解码为图片文件3. 示例使用注意

使用Python实现获取屏幕像素颜色值

《使用Python实现获取屏幕像素颜色值》这篇文章主要为大家详细介绍了如何使用Python实现获取屏幕像素颜色值,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、一个小工具,按住F10键,颜色值会跟着显示。完整代码import tkinter as tkimport pyau