鸭子类型在软件开发中意味着什么?


当前回答

Duck Typing:

let anAnimal 

if (some condition) 
  anAnimal = getHorse()
else
  anAnimal = getDog()

anAnimal.walk()

上述函数调用在结构类型中无效

以下将适用于结构类型:

IAnimal anAnimal

if (some condition) 
      anAnimal = getHorse()
    else
      anAnimal = getDog()
    
anAnimal.walk()

这就是所有的,我们中的许多人已经直观地知道鸭子打字。

其他回答

它是一个用于没有强类型的动态语言中的术语。

其思想是,为了调用对象上的现有方法,您不需要指定类型——如果在对象上定义了方法,则可以调用它。

这个名字来源于一句话“如果它看起来像鸭子,叫起来像鸭子,那它就是鸭子”。

维基百科有更多的信息。

维基百科有相当详细的解释:

http://en.wikipedia.org/wiki/Duck_typing

鸭子打字是一种动态的风格 输入一个对象的电流 方法和属性集 而是确定有效的语义 比它从一个特定的继承 类的实现 接口。

重要的是,使用duck类型时,开发人员可能更关心被使用的对象部分,而不是实际的底层类型是什么。

看看语言本身可能会有所帮助;它经常帮助我(我的母语不是英语)。

在鸭子打字中:

1)打字这个词并不是指在键盘上打字(就像我脑海中一直存在的形象那样),而是指确定“那是什么类型的东西?”

2) duck这个词表示决定是如何完成的;这是一种“松散的”定语,比如:“如果它像鸭子一样走路……那它就是一只鸭子。”之所以说“松散”,是因为这个东西可能是一只鸭子,也可能不是,但它是否真的是一只鸭子并不重要;重要的是我能像对待鸭子一样对待它,期待鸭子表现出的行为。我可以喂它面包屑,它可能会向我扑来,向我冲来,或者后退……但它不会像灰熊那样把我吃掉。

我试着用自己的方式去理解这句名言: “Python并不关心对象是否是真正的鸭子。 它只关心这个物体,首先‘呱呱’,其次‘像鸭子一样’。”

有一个很好的网站。http://www.voidspace.org.uk/python/articles/duck_typing.shtml#id14

作者指出,鸭子类型允许您创建自己的类 它们自己的内部数据结构-但使用正常的Python语法访问。

鸭子打字不是类型提示!

基本上,为了使用“duck typing”,你不会针对特定的类型,而是通过使用公共接口来针对更广泛的子类型(不是谈论继承,当我指的子类型时,我指的是适合相同配置文件的“事物”)。

你可以想象一个存储信息的系统。为了读写信息,你需要某种存储空间和信息。

存储类型可以是:文件、数据库、会话等。

无论存储类型是什么,该接口都会让您知道可用的选项(方法),这意味着在这一点上什么都没有实现!换句话说,接口不知道如何存储信息。

每个存储系统都必须通过实现接口的相同方法来知道接口的存在。

interface StorageInterface
{
   public function write(string $key, array $value): bool;
   public function read(string $key): array;
}


class File implements StorageInterface
{
    public function read(string $key): array {
        //reading from a file
    }

    public function write(string $key, array $value): bool {
         //writing in a file implementation
    }
}


class Session implements StorageInterface
{
    public function read(string $key): array {
        //reading from a session
    }

    public function write(string $key, array $value): bool {
         //writing in a session implementation
    }
}


class Storage implements StorageInterface
{
    private $_storage = null;

    function __construct(StorageInterface $storage) {
        $this->_storage = $storage;
    }

    public function read(string $key): array {
        return $this->_storage->read($key);
    }

    public function write(string $key, array $value): bool {
        return ($this->_storage->write($key, $value)) ? true : false;
    }
}

所以现在,每次你需要写/读信息时:

$file = new Storage(new File());
$file->write('filename', ['information'] );
echo $file->read('filename');

$session = new Storage(new Session());
$session->write('filename', ['information'] );
echo $session->read('filename');

在这个例子中,你最终在存储构造函数中使用Duck Typing:

function __construct(StorageInterface $storage) ...

希望能有所帮助;)