编程语言开发实践,如何将golang风格的接口编译成c++?
Programming language development practice, how to compile golang style interfaces to c++?
为了好玩,我一直在研究自己的可编译为 C++ 的编程语言。虽然大多数东西打印起来都相当简单,但我一直无法将我的 golang 样式接口编译为 c++。在 golang 中,您不需要显式声明特定结构实现接口,如果结构具有接口中声明的所有函数,它会自动发生。最初我打算用所有虚拟方法将接口编译成 class
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 界面分解为单一功能界面。通过其唯一签名散列所有接口。现在,为您的具体 类.
查找一组 C++ 抽象接口变成了一个 O(N) 操作
同样,当你消费一个对象时,你会找到所有被消费的接口。按照同样的逻辑,现在是 O(M)。编译器的总复杂度变为 O(N)+O(M) 而不是 O(N*M)。
轻微的缺点是您将在 C++ 中拥有 O(N) 个 vtable。如果某些接口总是组合在一起,其中一些可能会被合并。
为了好玩,我一直在研究自己的可编译为 C++ 的编程语言。虽然大多数东西打印起来都相当简单,但我一直无法将我的 golang 样式接口编译为 c++。在 golang 中,您不需要显式声明特定结构实现接口,如果结构具有接口中声明的所有函数,它会自动发生。最初我打算用所有虚拟方法将接口编译成 class
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 界面分解为单一功能界面。通过其唯一签名散列所有接口。现在,为您的具体 类.
查找一组 C++ 抽象接口变成了一个 O(N) 操作同样,当你消费一个对象时,你会找到所有被消费的接口。按照同样的逻辑,现在是 O(M)。编译器的总复杂度变为 O(N)+O(M) 而不是 O(N*M)。
轻微的缺点是您将在 C++ 中拥有 O(N) 个 vtable。如果某些接口总是组合在一起,其中一些可能会被合并。