C 代码的 Vala 泛型

Vala generics to C code

我正在阅读有关 vala 语言的信息,它可以编译为 Ansi C 代码。但是我也看到它支持像 Java 或 Rust 这样的泛型。现在我的问题是这是如何编译成 C 代码的?如果我有一个泛型 class 或函数,会生成什么样的 C 代码来模拟泛型行为?

Vala 泛型基于 gpointerGType

您只能使用基于指针的类型参数来特化泛型 class。

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;
}

您可以通过-C参数自行查看生成的代码:

valac -C Main.vala --pkg gee-0.8

这将生成一个 main.c 文件。如果你仔细阅读它,你会发现 MyClass 只有一个结构(加上一些额外的帮助结构,这些结构是基于 GObject classes 所需的)有一个成员 gpointer val,它还有一个 GType t_type 以及 t_dup_funct_destroy_func.

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

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

为确保传递的类型正确GLib type checking。这使得 Vala 泛型类型安全(部分在编译时,部分在运行时)。

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

我写 "partially at compile time" 因为 Vala 编译器足够聪明,当它知道赋值总是正确时,会省略 C 代码中的类型检查。

此外,Vala 生成的 C 代码旨在方便其他具有 GLib 绑定​​的编程语言(如 C、Python、C++、GJS 等)使用