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) //因为唐老鸭实现了所有鸭子的函数,所以可以这么用
}
本文来自博客园,作者:我爱吃炒鸡,转载请注明原文链接:https://www.cnblogs.com/chinaliuhan/p/15079875.html