编程语言开发实践,如何将golang风格的接口编译到c++



为了好玩,我一直在开发自己的编程语言,可以编译到C++。虽然大多数东西打印起来都很简单,但我在将golang风格的接口编译到c++时遇到了麻烦。在golang中,您不需要显式声明特定结构实现了一个接口,如果该结构具有接口中声明的所有函数,则会自动发生这种情况。最初我打算把接口编译成一个类,里面有所有的虚拟方法,比如

class MyInterface {
public:
void DoSomthing() = 0;
}

所有的实现结构都会像在c++中一样简单地从接口扩展

class MyClass: public MyInterface {
// ...
}

然而,这意味着我的编译器必须遍历源代码中定义的每个接口(以及所有依赖项(以及源代码中的每个结构,并检查该结构是否使用需要O(N*M(时间的操作来实现接口,其中N是结构的数量,M是接口的数量。我做了一些搜索,在这里偶然发现了一些c++代码:http://wall.org/~lewis/2012/07/23/go-style-interfaces-in-cpp.html使c++中的golang风格接口成为现实,在这种情况下,我可以将接口编译成类似的代码(尽管不完全是因为我不太愿意使用原始指针而不是智能指针(,而不必担心显式实现它们。然而,作者指出,不应该对生产代码这样做,这让我有点担心。

这是一个有点主观的问题,但任何有更多C++知识的人都能告诉我,按照文章中建议的方式做这件事是否真的是个坏主意,或者它实际上没有那么糟糕,可以做到,或者是否有更好的方法来写C++代码,让我在不使用O(N*M(循环的情况下实现我想要的行为?

我最初的想法是利用C++支持多重继承这一事实。将golang接口分解为单个功能接口。通过唯一签名对所有接口进行哈希。现在它变成了一个O(N(操作,为您的具体类找到一组C++抽象接口。

类似地,当您消费一个对象时,您会找到所有消费的接口。现在,这是O(M(的相同逻辑。编译器的总复杂度变为O(N(+O(M(,而不是O(N*M(。

稍微有点不利的是,C++中会有O(N(个vtables。如果某些接口总是组合在一起,那么其中一些可能会被合并。

最新更新