Vala泛型到C代码

Vala泛型到C代码,c,generics,compiler-construction,vala,C,Generics,Compiler Construction,Vala,我在读有关vala语言的书,它编译成Ansi C代码。然而,我也看到它支持Java或Rust之类的泛型。现在我的问题是如何将其编译成C代码?如果我有一个gerneric类或函数,会生成什么样的C代码来模拟泛型行为?Vala泛型基于gpointer和GType 只能使用基于指针的类型参数专门化泛型类 class MyClass<T> { public T val; } public static int main (string[] args) { // This wou

我在读有关vala语言的书,它编译成Ansi C代码。然而,我也看到它支持Java或Rust之类的泛型。现在我的问题是如何将其编译成C代码?如果我有一个gerneric类或函数,会生成什么样的C代码来模拟泛型行为?

Vala泛型基于
gpointer
GType

只能使用基于指针的类型参数专门化泛型类

class MyClass<T> {

public T val;

}

public static int main (string[] args) {
    // This wouldn't compile!
    // var il = new Gee.ArrayList<int> ();

    var il = new Gee.ArrayList<int?> ();
    var dl = new Gee.ArrayList<double?> ();
    il.add (5);
    dl.add (3.0);

    var im = new MyClass<int?>();
    im.val = 5;

    var dm = new MyClass<double?>();
    dm.val = 3.0;

    var lm = new MyClass< Gee.List<int?> > ();
    lm.val = il;

    return 0;
}
这将生成一个
main.c
文件。如果仔细阅读,您将看到MyClass只有一个结构(加上基于GObject的类所需的一些附加帮助器结构),它有一个成员
gpointer val
,它还有一个
GType t_type
以及
t_dup_func
t_destroy_func

struct _MyClass {
        // ...
        gpointer val;
};

struct _MyClassPrivate {
        GType t_type;
        GBoxedCopyFunc t_dup_func;
        GDestroyNotify t_destroy_func;
};
以确保执行正确的类型传入。这使得Vala泛型类型安全(部分在编译时,部分在运行时)

这与编译时扩展的C++模板形成了鲜明的对比。与经典的C++模板相比,它更接近于C泛型。 我之所以写“部分在编译时”,是因为Vala编译器足够聪明,当它知道赋值总是正确的时候,就可以省略C代码中的类型检查


Vala生成的C代码对于其他具有GLIB绑定的编程语言(如C、Python、C++、GJS等)来说是容易消耗的。

假设你编写了一个通用的代码>列表< /代码>,然后使用<代码>列表和<代码>列表。Vala编译器将编写具有适当行为的C结构
list_int
list_double
。换句话说,实例化一个特定的泛型的工作是由Vala完成的。这不是和C++模板一样吗?但是,模板并没有完全和泛型的行为相同。C++模板的行为类似于C泛型(如所解释的)。Vala泛型将为您传递的每个通用参数创建实际结构。C++模板不编译成C代码,但概念是相同的。当然,C结构是按照Vala规范来编写正确的行为的,而不是C++或C语言所说的。@ NWP只创建了一个C结构,请看我的答案。
struct _MyClass {
        // ...
        gpointer val;
};

struct _MyClassPrivate {
        GType t_type;
        GBoxedCopyFunc t_dup_func;
        GDestroyNotify t_destroy_func;
};