Vala泛型为C代码

Exa*_*gon 3 c compiler-construction generics vala

我正在阅读语言vala,它编译成Ansi C代码.但是我也看到它支持Java或Rust等泛型.现在我的问题是如何将其编译为C代码?如果我有一个泛型类或函数,生成什么样的C代码来模拟通用行为?

Jen*_*off 6

Vala仿制药基于gpointerGType.

您只能使用基于指针的类型参数来专门化Generic类.

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;
}
Run Code Online (Sandbox Code Playgroud)

您可以使用以下-C参数自行检查生成的代码:

valac -C Main.vala --pkg gee-0.8
Run Code Online (Sandbox Code Playgroud)

这将生成一个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;
};
Run Code Online (Sandbox Code Playgroud)

为了确保在GLib中传递正确的类型,执行类型检查.这使得Vala泛型类型安全(部分在编译时,部分在运行时).

这与在编译时扩展的C++模板形成对比.所以它更接近C#泛型而不是经典的C++模板.

我写了"部分在编译时",因为Vala编译器足够聪明,当它知道赋值总是正确时,可以省略C代码中的类型检查.

此外,Vala生成的C代码对于具有GLib绑定的其他编程语言(如C,Python,C++,GJS等)也很容易使用.