有没有用这种语言(例如 C#、Java)写过东西,却错过了鸭子打字的情况?(有关反对鸭子类型的论点,请参阅此问题)
4 回答
每次您需要使用不属于您的代码并且没有适当的抽象(HttpContext 任何人?)。由于您不能让自己的方法接受 IHttpContext,因为 HttpContext 类型没有那种抽象,所以您必须满足于 Adapter 和/或 Factory 等。如果你能在你的代码中定义 IHttpContext 契约,让它看起来像 HttpContext,将你的方法设置为接受 IHttpContext,并传入一个真实的、真实的 HttpContext 对象来躲入 IHttpContext,那就更好了。
绝不。自 90 年代以来一直使用 Java,自 01 年左右开始使用 Python。
这就是为什么我从来没有错过在 Java 中输入鸭子的原因。
“Java 中的鸭子打字问题”实际上是关于理解多态性的绝对失败。如果您曾经认为您需要任何类型的运行时类型识别或“isinstance”功能,那么您就没有掌握多态性并且您做错了。
请参阅Programmer Ignorance Pet Peeve问题。未能掌握多态性是一个大问题,并导致这种“Java 中的鸭子类型”错误。
如果你了解多态,你就不需要鸭子类型,在 Python 和 Java 之间切换时也不会错过它。
在相关的说明中,我只使用 Pythonisinstance()
作为断言的一部分,以使需要整数的函数在它获得非整数时爆炸。 isinstance()
有时与 Java 中的尝试一起使用,以进行类似鸭子类型的事情。
关键是我老了(52)而且不是很聪明。所以我必须在 Python 中保持“强”类层次结构,否则我会感到困惑。我总是在 Python 设计中留出空间,以便在必要时重构为更严格的类层次结构。
另一个问题与鸭子打字无关。无论如何,假设这不会关闭,我会说我真正想念鸭子打字的一次是在尝试使用大型 API 测试类时。我们需要一个单独的框架来创建它们的模拟,而在另一种编程语言中,您可以想象只需传入一个实现您所需要的基本基础的自写类。
例如,尝试在没有框架的情况下在 java 中模拟 JDBC ResultSet,这有点痛苦。
foreach
在语言试图解决设计弱点的情况(如 C#构造的情况)之外,永远不需要让语言基于方法签名执行鸭子类型。另一方面,在很多情况下,使用接口做类似于鸭式打字的事情会很有帮助。例如,如果一个方法UseDuck
采用一个泛型参数,该参数被限制为实现接口IWalkLikeDuck
和IQuackLikeDuck
,则代码具有一个泛型类型的变量,该变量被限制为实现这两者IWalkLikeDuck
并IQuackLikeDuck
可以将其传递给UseDuck
. 但是,没有好的方法可以让代码以一种可以在Wowzo
退出后传递的形式将其持久化。如果可以定义一个鸭子类型,那将非常有帮助IWalkAndTalkLikeDuck
它继承自其他两个接口,但会自动被视为由实现了IWalklikeDuck
andITalkLikeDuck
的任何类实现,这样就可以将已知实现的任何类型的引用存储IWalkLikeDuck
到ITalkLikeDuck
aList<IWalkAndTalkLikeDuck>
中。