Language agnostic 如何在动态语言中实现类?
如何在动态语言中实现类 我知道Javascript使用的是一个原型模式(在“某处”有一个未绑定JS函数的容器,当通过对象调用它们时,这些函数是绑定的),但我不知道它在其他语言中是如何工作的 我对此很好奇,因为我想不出一种有效的方法,通过复制每个实例的成员来拥有本机绑定方法而不浪费内存和/或cpu (通过绑定方法,我的意思是以下代码应该可以工作:)Language agnostic 如何在动态语言中实现类?,language-agnostic,programming-languages,Language Agnostic,Programming Languages,如何在动态语言中实现类 我知道Javascript使用的是一个原型模式(在“某处”有一个未绑定JS函数的容器,当通过对象调用它们时,这些函数是绑定的),但我不知道它在其他语言中是如何工作的 我对此很好奇,因为我想不出一种有效的方法,通过复制每个实例的成员来拥有本机绑定方法而不浪费内存和/或cpu (通过绑定方法,我的意思是以下代码应该可以工作:) 这在很大程度上取决于语言和实现。我会告诉你我对CPython和PyPy的了解 总的想法是这样的,这也是CPython在大部分情况下所做的: 每个对象都
这在很大程度上取决于语言和实现。我会告诉你我对CPython和PyPy的了解 总的想法是这样的,这也是CPython在大部分情况下所做的:
\uuuuu getattr\uuuu
和\uuu getattribute\uuuu
这样的神奇方法来更改)\uuuu get\uuu
方法,类的查找结果可能会被它所生成的对象劫持。更重要的是,这个\uuuuuu get\uuuuu
方法被告知是在实例上还是在“所有者”(类)上开始查找
在Python2中,我们有一个丑陋且不必要的UnboundMethod
描述符(除了\uuuu get\uuuu
方法之外),它简单地包装函数,在类上抛出错误。如果self
不是可接受的类型,则方法(self)
。在Python3中,\uuuuu get\uuuu
只是所有函数对象的一部分,而未绑定的方法就不存在了。在这两种情况下,\uuu get\uuu
方法在您查找类时返回自身(因此您可以使用class.method
,这在少数情况下很有用),在您查找对象时返回“绑定方法”对象。这个绑定方法对象只不过是存储原始函数和实例,并将后者作为第一个参数在其\uuuuu调用\uuuu
中传递给前者(覆盖函数调用语法的特殊方法)
因此,对于CPython:虽然绑定方法有成本,但它比您想象的要小。在空间方面只需要两个引用,CPU成本仅限于较小的内存分配,并且在调用时需要额外的间接寻址。但是请注意,这种代价适用于所有方法调用,而不仅仅是那些实际使用绑定方法特性的方法调用a.f()
必须调用描述符并使用其返回值,因为在动态语言中,我们不知道是否对其进行了猴子补丁以执行不同的操作
在PyPy中,事情更有趣。由于它是一个不会在正确性上妥协的实现,因此上述模型在语义推理方面仍然是正确的。然而,它实际上更快。除了JIT编译器内联然后在大多数情况下消除上面描述的整个混乱之外,它们还可以在字节码级别解决这个问题。在a.f()
的情况下,有两种方法保留了语义,但省略了绑定方法对象的分配。还有一种方法可以简化查找过程,但需要一些额外的簿记(尽管一些簿记已经为JIT完成)
class Foo { function bar() : return 42; };
var test = new Foo();
var method = test.bar;
method() == 42;