鸭子类型在软件开发中意味着什么?
当前回答
鸭子打字不是类型提示!
基本上,为了使用“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) ...
希望能有所帮助;)
其他回答
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()
这就是所有的,我们中的许多人已经直观地知道鸭子打字。
用鸭子打字技术的树遍历
def traverse(t):
try:
t.label()
except AttributeError:
print(t, end=" ")
else:
# Now we know that t.node is defined
print('(', t.label(), end=" ")
for child in t:
traverse(child)
print(')', end=" ")
在编程中,类型可以分为名义类型和结构类型。名义类型考虑类型的整个结构。从谁那里继承的等等。它们显然比结构类型更复杂。例如,在c#和Java中使用名义类型。
结构类型根本不考虑这些问题。对于结构类型,只有单一类型的结构是重要的。这是什么样子。在一个类的例子中。它是否具有相同的参数和预期的类型。这叫做鸭子打字。Duck Typing起源于Duck Test。
Dugtest的意思是:如果某物看起来像鸭子。如果它像鸭子一样游泳。如果它像鸭子一样嘎嘎叫。然后它是一只鸭子。相反地:如果一个测试用例不应用,那么它就不是鸭子。(https://en.wikipedia.org/wiki/Duck_test)
我试着用自己的方式去理解这句名言: “Python并不关心对象是否是真正的鸭子。 它只关心这个物体,首先‘呱呱’,其次‘像鸭子一样’。”
有一个很好的网站。http://www.voidspace.org.uk/python/articles/duck_typing.shtml#id14
作者指出,鸭子类型允许您创建自己的类 它们自己的内部数据结构-但使用正常的Python语法访问。
Duck typing:
如果它像鸭子一样说话和走路,那么它就是一只鸭子
这通常被称为诱拐(诱拐推理或也称为归纳,我认为一个更清晰的定义):
从C(结论,我们所看到的)和R(规则,我们所知道的),我们接受/决定/假设P(前提,属性),换句话说,一个给定的事实 ... 医学诊断的基础 和鸭子:C =走路,说话,R =像鸭子,P =它是一只鸭子
回到编程:
对象o有方法/属性mp1和接口/类型T 要求/定义mp1 对象o有方法/属性mp2,接口/类型T要求/定义mp2 ...
因此,不仅仅是简单地接受mp1…在任何对象上,只要它满足mp1的某些定义…,编译器/运行时也应该接受断言o是类型T
上面的例子是这样的吗?Duck输入实质上就是没有输入吗?或者我们应该称之为隐式类型?