2016-07-04 8 views
2

言語valaについて読んでいて、Ansi Cコードにコンパイルしています。しかし、私はJavaやRustのようなジェネリックをサポートしていることも知っていました。今私の質問は、これがどのようにCコードにコンパイルされているのですか? gernericクラスまたは関数を持っている場合、一般的な動作をシミュレートするためにどのようなCコードが生成されますか?バラのジェネリックスをCコード

+0

セイ(C、PythonやC++、GJS、などのように)あなたは、汎用 'リストを書き'と他のプログラミング言語のための消耗品れることを意図されて生成されました'リスト'と 'リスト'を使用してください。 Valaコンパイラは、適切な振る舞いを持つC構造体 'list_int'と' list_double'を記述します。言い換えれば、特定のジェネリックをインスタンス化する作業はValaによって行われます。 – nwp

+1

これはC++テンプレートと同じではないでしょうか?しかし、テンプレートはジェネリックとまったく同じ振る舞いをしていません。 – Exagon

+0

C++テンプレートは、C#のジェネリックスと同様に動作します([ここ](http://stackoverflow.com/a/31929/69809)で説明されています)。これはvalaジェネリックスが渡すジェネリックパラメータごとに実際の構造体を作成するのと同じ方法です。 – Groo

答えて

5

バラのジェネリックは、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; 
} 

あなたは-Cパラメータで生成されたコードを自分でチェックすることができます。

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

これはmain.cファイルを生成します。注意深く読んだ場合、メンバgpointer valを持つMyClass(GObjectベースのクラスに必要ないくつかの追加のヘルパー構造に加えて)の構造体が1つしかないことがわかります。GType t_typet_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++のテンプレートよりもC#のジェネリックに近いです。

Valaコンパイラは、割り当てが常に正しいことがわかっているときに、Cコードの型チェックを省略するほどスマートなので、 "部分的にコンパイル時に"書きました。

はまた、Valaのは、Cのコードが簡単にGLibのバインディングを持っている

関連する問題