强类型 OOP 语言中鸭子类型的争论?
是否有这样的情况:您用这种语言(例如 C#、Java)编写了一些东西,却错过了鸭子类型? (参见这个问题 反对鸭子类型的论据)
Is there a case where you wrote something in such a language (e.g. C#, Java), and missed duck typing? (See this question for arguments against duck typing)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
每次您需要使用不属于您的代码,并且没有适当的抽象(HttpContext 有人吗?)。 由于您不能让您的方法接受 IHttpContext,因为 HttpContext 类型没有这种抽象,因此您必须满足于 Adapter 和/或 Factory 等。
如果您可以在代码中定义 IHttpContext 协定,使其看起来像 HttpContext,将您的方法设置为接受 IHttpContext,并传入一个真正的、真实的 HttpContext 对象以鸭入 IHttpContext,那就更好了。
Every time you need to work with code that you do not own, and that does not have proper abstraction (HttpContext anyone?). As you can't have a method of yours accept IHttpContext, since HttpContext type does not have that kind of abstraction, you have to settle for an Adapter and/or Factory and such.
Would have been extremely nicer if you could have defined the IHttpContext contract in your code, make it look like the HttpContext, set your method to accept IHttpContext, and have a true, real HttpContext object passed in to duck into IHttpContext.
另一个问题与鸭子打字无关。 不管怎样,假设这没有结束,我会说我真正怀念鸭子打字的一次是在尝试使用大型 API 测试类时。 我们需要一个单独的框架来创建它们的模拟,而在另一种编程语言中,您可以想象只需传递一个自编写的类来实现您所需的基本基础知识。
例如,尝试在没有框架的情况下用 java 模拟 JDBC ResultSet,这有点痛苦。
That other question had little to do with duck typing. Anyway, assuming this doesn't get closed I'd say the one time I really miss duck typing is when trying to test classes with big API's. We need a separate framework to create mocks of them while in another programming language you could conceivably just pass in a self written class that implements the bare basics of what you need.
For instance, try to mock a JDBC ResultSet in java without a framework, it's a bit of a pain.
绝不。 从 90 年代开始使用 Java,从 01 年左右开始使用 Python。
这就是为什么我从来没有错过 Java 中的鸭子类型。
“Java 中的 Duck Typing 问题”实际上是关于对多态性的绝对失败。 如果您曾经认为需要任何类型的运行时类型识别或“isinstance”功能,那么您就没有掌握多态性,并且您做错了。
请参阅程序员无知惹恼问题。 未能掌握多态性是一个大问题,并会导致这种“Java 中的鸭子类型”错误。
如果您了解多态性,那么您就不需要鸭子类型,并且在 Python 和 Java 之间切换时也不会错过它。
与此相关的是,我只使用 Python 的 isinstance() 作为断言的一部分来创建一个需要整数的函数,当它获得非整数时就会爆炸。 isinstance() 有时会在 Java 中尝试执行类似鸭子类型的操作。
关键是我老了(52岁)而且不太聪明。 所以我必须在 Python 中保持“强”的类层次结构,否则我会感到困惑。 我总是在 Python 设计中留出空间,以便在必要时重构为更严格的类层次结构。
Never. Been using Java since the '90's and Python since '01 or so.
Here's why I never missed duck typing in Java.
The "Duck Typing in Java Question" is really about an absolute failure to understand Polymorphism. If you ever think you need any kind of run-time type identification or "isinstance" functionality, you've failed to grasp Polymorphism and you're doing it wrong.
See the Programmer Ignorance Pet Peeve question. Failure to grasp polymorphism is a huge problem and leads to this "duck typing in Java" mistake.
If you understand polymorphism, you don't need duck typing and you don't miss it when switching between Python and Java.
On a related note, I only use Python's
isinstance()
as part of an assertion to make a function that requires integers blow up when it gets a non-integer.isinstance()
is sometimes used with attempts in Java to do duck-typing-like things.The point is that I'm old (52) and not very smart. So I have to keep to a "strong-ish" class hierarchy in Python or I get confused. I always left a space in a Python design for refactoring into more strict class hierarchy if it become necessary.
除了语言试图解决设计缺陷的情况(如 C#
foreach
构造的情况)之外,永远不需要让语言基于方法签名执行鸭子类型。 另一方面,在很多情况下,使用接口执行类似于鸭子类型的操作会很有帮助。 例如,如果有一个方法UseDuck
,它采用一个通用参数,该参数被限制为实现接口IWalkLikeDuck
和IQuackLikeDuck
,则代码的变量为仅限于实现IWalkLikeDuck
和IQuackLikeDuck
的泛型类型可以将其传递给UseDuck
。 然而,没有什么好的方法可以让代码以某种形式持久保存它,以便在退出时可以将其传递给Wowzo
。 如果可以定义一个从其他两个接口继承的鸭子类型的IWalkAndTalkLikeDuck
将会非常有帮助,但是将自动被视为由同时实现IWalklikeDuck 的任何类实现
和ITalkLikeDuck
,这样就可以存储对已知实现IWalkLikeDuck
和ITalkLikeDuck
的任何类型的引用进入List
。Having a language perform duck-typing based upon method signatures should never be necessary outside situations where a language is trying to work around a design weakness (as was the case with C#
foreach
construct). On the other hand, there are many situations where it would be helpful to do something similar to duck-typing with interfaces. For example, if one has a methodUseDuck
which takes a generic parameter that's constrained to implement interfacesIWalkLikeDuck
andIQuackLikeDuck
, code which has an variable of a generic type which is constrained to implement bothIWalkLikeDuck
andIQuackLikeDuck
can pass it toUseDuck
. There is no nice way, however, for the code to persist it in a form which can be passed toWowzo
once it exits. It would be very helpful if one could define a duck-typedIWalkAndTalkLikeDuck
which inherited from both of the other interfaces, but would automatically be regarded as implemented by any class which implements bothIWalklikeDuck
andITalkLikeDuck
, such that one could store a reference to any type which was know to implementIWalkLikeDuck
andITalkLikeDuck
into aList<IWalkAndTalkLikeDuck>
.