"鸭子打字"这个名字后面有一个故事,我听说过'如果它看起来像一只鸭子,听起来像一只鸭子,我们称它为鸭子'(或类似的东西),但为什么一个鸭?为什么不``如果它看起来像一个_并且听起来像_,让我们称之为_''.
这听起来像飞行马戏团的素描,但我不记得了.名字背后有故事吗?
题:
有没有办法用Delphi 2007进行鸭子打字(即没有泛型和高级Rtti功能)?
Duck为Delphi 2010打字资源:
最后编辑:
我已经深入研究了上面列出的资源,并在这里研究了每个发布的答案.
有人可以解释一下Refused Bequest的含义吗?我尝试阅读一些文章,并说它是一种代码气味,或者在wiki中它告诉它它是一个类,它覆盖基类的方法,使得基类的契约不受派生类的尊重.
但简而言之,或者更简单的说法,实际上是什么?
从文档中
duckmap将对每个元素应用和阻止,并返回一个新的列表,其中包含块的已定义返回值.对于未定义的返回值,如果该元素实现了Iterable,则duckmap将尝试进入该元素.
但是之后:
my $list = [[1,2,3],[[4,5],6,7]];
say $list.deepmap( *² ); # [[1 4 9] [[16 25] 36 49]]
say $list.duckmap( *² ); # [9 9]
Run Code Online (Sandbox Code Playgroud)
deepmap的表现与预期相似,但我无法理解duckmap
正在做什么.这个问题与perl6/doc中的这个问题有关.它可以通过"它们无法更加不同"来解决,但我想找到一些例子,他们也会这样做,当他们不这样做时,试着去了解真正发生的事情.
recursion functional-programming duck-typing perl6 map-function
在C#中,如果一个类具有接口的所有正确方法/签名,但没有明确地实现它,如:
class foo : IDoo {}
Run Code Online (Sandbox Code Playgroud)
该类仍然可以作为该接口进行转换吗?
问题:我希望能够在Java中一般地访问Java ojbect上的任何属性/字段,类似于动态语言(想想Groovy,JavaScript)的方式.我不知道当时我正在编写这个管道代码它是什么类型的对象或属性/字段名称是什么.但是当我去使用它时,我会知道属性/字段名称.
我目前的解决方案:到目前为止,我已经编写了一个简单的包装类,用于java.beans.Introspector
获取Bean/POJO的属性并将它们公开为Map<String, Object>
.它很粗糙但适用于简单的情况.
我的问题是除了反射/转换为Map之外还有哪些方法可以解决这个问题?
在我走上这条道路之前,我想知道是否有人知道我如何能够从Rhino中蚕食一些东西,或者javax.script.*
是否有一个经过深思熟虑的实施这个概念的东西.或者也许是一种我没有考虑过的完全不同的方法.
编辑:是的我熟悉反射(我相信它是Introspector在引擎盖下使用的东西).如果还有其他经过深思熟虑的解决方案,我只是很好奇.
编辑2:似乎最流行的答案涉及1)直接或通过辅助类反映,和/或2)映射到实现所需类成员的接口.关于利用Groovy的评论,我真的很感兴趣.由于Groovy具有真正的duck-typing并且它是一种JVM语言,有没有办法在Groovy中创建一个简单的帮助器并从Java调用它?这将非常酷,可能更灵活,性能更好.
答:我认为Mike的答案是最好的,因为它是一个最接近的完整概念.对于这种特殊情况,我可能不会采用这种方式,但它肯定是一种有用的方法.任何看过这个的人都应该确保阅读这里的对话,因为那里有很多有用的信息.
谢谢!
这是一些Ruby代码:
class Duck
def help
puts "Quaaaaaack!"
end
end
class Person
def help
puts "Heeeelp!"
end
end
def InTheForest x
x.help
end
donald = Duck.new
john = Person.new
print "Donald in the forest: "
InTheForest donald
print "John in the forest: "
InTheForest john
Run Code Online (Sandbox Code Playgroud)
而且,我把它翻译成Python:
import sys
class Duck:
def help():
print("Quaaaaaack!")
class Person:
def help():
print("Heeeelp!")
def InTheForest(x):
x.help()
donald = Duck()
john = Person()
sys.stdout.write("Donald in the forest: ")
InTheForest(donald)
sys.stdout.write("John in the forest: ")
InTheForest(john)
Run Code Online (Sandbox Code Playgroud)
结果是一样的.这是否意味着我的Python代码使用duck-typing?我找不到一个鸭子打字的例子,所以我想在Python中可能没有鸭子打字.维基百科中有代码 …
我看到许多人说"eval是邪恶的/危险的/不安全的",因为人们可以这样做:
eval("os.system('rm -rf /')")
Run Code Online (Sandbox Code Playgroud)
而在其他帖子中,pythoner被认为是" 同意成人 ",你不必进行类型检查,因为python是鸭子打字的样式.
那么下面的代码呢:
def foo(duck):
duck.quack()
class EvilDuck(object):
def quack(self):
os.system('rm -rf /')
foo(EvilDuck())
Run Code Online (Sandbox Code Playgroud)
你通常如何避免这种情况?pythoner何时同意成年人,何时不同意?
TypeScript使用编译时(静态)duck typing.
我喜欢扩展原始类型以防止不正确的替换.例如,我喜欢给信用卡号码变量一个信用卡号码类型,而不是整数.我最近尝试使用一对扩展String的接口在TypeScript中执行此操作,并发现它们可以自由地替换彼此(并且该字符串替代两者).
我真的很想得到编译时的标称输入.有任何想法吗?
在 Rust 中,一个明确的类型impl Trait for Object
保证了它Object
具有这一特性。现在,C++20 概念当然更加笼统一些,因为它们不仅仅与一种类型相关联,而且可能与多种类型相关联。然而,这引出了一个问题:如何确定您实现的某些类型实际上满足某些概念。
现在的概念有点鸭子式,如果你的对象满足了有人试图在一个requires
块中用它做的所有事情(它像鸭子一样嘎嘎叫),那么它就会像鸭子一样传递并满足这个概念。但是有没有办法说:“我希望这个分类的类能够通过测试”?
例如,这可能看起来像这样:
class MyClass1 { ... }
class MyClass2 { ... }
template<typename T1, T2>
concept MyConcept = requires(T1 t1, T2 t2) { ... }
static_assert( satisfies<MyConcept, MyClass1, MyClass2>() )
Run Code Online (Sandbox Code Playgroud)
这样的函数是否satisfies
存在,如果不存在:如何编写这样的satisfies
函数?
如果您将对象传递到某些概念的实现是可选的库(例如,接受可能位于或不位于边界的组件并且仅对位于边界的对象执行某些计算的库),则 Ducktyping 可能还不够。
template <typename GeneralComponent>
void do_something_optionally(GeneralComponent component) {
if constexpr ( satisfies<isBorder, GeneralComponent>() ) {
do_border_calculation(component);
} else {
// don't do border calculation
}
}
do_border_calculation(isBorder …
Run Code Online (Sandbox Code Playgroud) duck-typing ×10
python ×2
.net ×1
c# ×1
c++ ×1
c++-concepts ×1
c++20 ×1
casting ×1
conventions ×1
delphi ×1
delphi-2007 ×1
groovy ×1
interface ×1
java ×1
liskov-substitution-principle ×1
map-function ×1
perl6 ×1
python-3.x ×1
recursion ×1
rhino ×1
typescript ×1