Loading

Golang的interface及duck typing鸭子类型

Golang的interface及duck typing鸭子类型

“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。” 意思就是: 一个东西究竟是不是鸭子,取决于它能不能满足鸭子的工作。

duck typing 多见于动态语言,例如PHP,Python等.

在静态语言中比较罕见,但是在go中duck typing处处都是duck typing.go的interface{}和duck typing密不可分.

原理说明

duck typing描述事物的外部行为而非内部结构

在面向对象的编程语言中,当某个地方(比如某个函数的参数)需要符合某个条件的变量(比如要求这个变量实现了某种方法)时,什么是判断这个变量是否“符合条件”的标准?

如果某种语言在这种情况下的标准是: 这个变量的类型是否实现了这个要求的方法(并不要求显式地声明),那么这种语言的类型系统就可以称为 duck typing

鸭子类型(英语:duck typing):

是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由"当前方法和属性的集合"决定。

个人理解,谁调用谁实现,比如你要调用一个A函数,而A函数中接收参数的同时调用了参数中的B方法.这时候你就要传进去一个具有B方法名的一个对象.

代码案例

对比Python3的duck typing案例

#!/usr/local/bin/python3
# coding=utf8

# 使用的对象和方法
class PsyDuck(object):
    def gaga(self):
        print("这是可达鸭")


# 使用的对象和方法
class DoningdDuck(object):
    def gaga(self):
        print("这是唐老鸭")


# 被调用的函数
def duckSay(func):
    return func.gaga()


# 限制调用方式
if __name__ != '__main__':
    print("must __main__")

# 实例化对象
duck = PsyDuck()
person = DoningdDuck()
# 调用函数
duckSay(duck)
duckSay(person)

GoLang案例

package main

import "fmt"

//定义一个鸭子接口
//Go 接口是一组方法的集合,可以理解为抽象的类型。它提供了一种非侵入式的接口。任何类型,只要实现了该接口中方法集,那么就属于这个类型。
type Duck interface {
	Gaga()
}

//假设现在有一个可达鸭类型
type PsyDuck struct{}
//可达鸭声明方法-满足鸭子会嘎嘎叫的特性
func (pd PsyDuck) Gaga() {
	fmt.Println("this is PsyDuck")
}

//假设现在有一个唐老鸭类型
type DonaldDuck struct{}
//唐老鸭声明方法-满足鸭子会嘎嘎叫的特性
func (dd DonaldDuck) Gaga() {
	fmt.Println("this is DoningdDuck")
}

//要调用的函数 - 负责执行鸭子能做的事情,注意这里的参数,有类型限制为Duck接口
func DuckSay(d Duck) {
	d.Gaga()
}


func main() {
	//提示开始打印
	fmt.Println("duck typing")

	//实例化对象
	var pd PsyDuck	//可达鸭类型
	var dd DonaldDuck	//唐老鸭类型

	//调用方法
	//pd.Gaga()	//因为可达鸭实现了所有鸭子的函数,所以可以这么用
	//dd.Gaga()	////因为唐老鸭实现了所有鸭子的函数,所以可以这么用
	DuckSay(pd)       //因为可达鸭实现了所有鸭子的函数,所以可以这么用
	DuckSay(dd)       //因为唐老鸭实现了所有鸭子的函数,所以可以这么用
}

posted @ 2021-07-30 15:39  我爱吃炒鸡  阅读(812)  评论(0编辑  收藏  举报