鸭子类型是什么鬼

刚刚看到 《Python Vs Go,鸭子类型,你有我也有》 了解到 鸭子类型,刚看到标题的时候,怪怪的,这是个什么鬼类型!而且总感觉 PegasusWang 稍微开了开车,哈哈!

在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由"当前方法和属性的集合"决定。这个概念的名字来源于由James Whitcomb Riley提出的鸭子测试,“鸭子测试”可以这样表述:

当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。^[在鸭子类型中,关注点在于对象的行为,能作什么;而不是关注对象所属的类型。–鸭子类型]

很明显在这里,我们更关注的是对象的行为而不是它们的类型。

举个🌰,定义一个鸭子类,其有个 方法,在定义一个人类(有一种男人被称为“🦆”),他也有 的方法,总感觉好搞笑!这里我们就可以认为它们都有叫的方法,都是鸭子的行为,所以都是鸭子!Python 试一下:

class Duck:
    def __init__(self, name):
        self.name = name

    def quack(self):
        print("呱呱")


class Man:
    def __init__(self, name):
        self.name = name

    def quack(self):
        print("女王大人")


def do_quack(ducker):
    ducker.quack()


if __name__ == '__main__':
    d = Duck('duck')
    m = Man('man')
    do_quack(d)
    do_quack(m)

PegasusWang 还用 Go 语言试了一下,使用了 interface 特性,咦!这与 swift 语言中的协议(protocol) 很像嘛,那咱用 swift 实现一下:

import Foundation

protocol Ducker {
    func quack()
}

class Duck: Ducker {
    
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
    func quack() {
        print("呱呱")
    }
}

class Man: Ducker {
    
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
    func quack() {
        print("女王大人")
    }
}

func doQuack(ducker: Ducker) {
    ducker.quack()
}

let d = Duck(name: "duck")
let m = Man(name: "man")

doQuack(ducker: d)
doQuack(ducker: m)

最终我们都能听见 duck 和 man 的叫声,Nice!

呱呱
女王大人